侧边栏壁纸
博主头像
luck博主等级

快乐的程序员

  • 累计撰写 83 篇文章
  • 累计创建 150 个标签
  • 累计收到 5 条评论
标签搜索

目 录CONTENT

文章目录

ElasticSearch的分词器

luck
2023-09-13 / 0 评论 / 1 点赞 / 176 阅读 / 2,596 字

前言

我们都知道,ES的核心功能之一便是全文本搜索,这种全文本搜索,可以返回相关的结果,而非精确的匹配结果。

这其中文本分析Analysis发挥了重要的作用,为什么索引一个文本字段如“My Name is Old Nico”,当搜索词组“My Nico”时可以搜索的到呢?

本文演示ES版本为8.6.2


概念

Text Analysis(文本分析)就是将一个非结构化的复杂文本(如商品描述)转换成结构化的词项的过程,也叫分词

分词是通过分词器Analyzer实现的。

分词器总共分为3个部分,不管是ES内置的还是自定义的,如下图所示:

  • Character filters
    输入是最原始的文本,进行处理,例如去除html等。它可以没有或者有多个,按顺序执行。

  • Tokenizer
    经过Character filters后的文本,按照规则进行分词,分成一个一个的Token(通常是单独的词),同时输出每个Token的起始位置和长度。每个分词器有一个唯一的Tokenizer。
    例如Standard Tokenizer、Letter Tokenizer、Whitespace Tokenizer等

  • Token filters
    经过Tokenizer拿到一系列的Token后,再通过Token filters进行Token的修改,例如移除英文停用词(is a等)、大写字母转小写、增加同义词等。它可以没有或者有多个,按顺序执行。


内置分词器

ES提供了可以适用大多数场景的内置分词器,可以很方便的使用它们,包括如下:

  • Standard Analyzer:标准的分词器按Unicode文本分割算法进行分割源文本,同时会移除标点符号、停用符,并将大写字母转成小写。也是默认分词器
  • Simple Analyzer:按照非字母字符进行分词,例如数字、空格、连接符等,并进行小写处理。
  • Whitespace Analyzer:按照空格进行切分,不进行小写处理。
  • Stop Analyzer:类似Simple分词器,同时过滤英文停用符(is a等,更多停用符),并进行小写处理。
  • Keyword Analyzer:不分词,直接将原文本输出。
  • Pattern Analyzer:正则表达式分词,默认 \W+(所有非文本字符),并进行小写处理。
  • Language Analyzers:提供了30多种常见语言的分词器,例如english。
  • Fingerprint Analyzer:使用了一种指纹识别算法进行分词,会进行去重。

特别说明Standard Analyzer

其它分词器详细说明可以查看官方文档>

Standard Analyzer包括:
Tokenizer:Standard Tokenizer
Token Filters:Lower Case Token Filter(小写处理)、Stop Token Filter (默认不生效)

接下来使用 _analyze api 进行测试,如下:

POST http://127.0.0.1:9200/_analyze
{
    "analyzer":"standard",
    "text": "The 2 QUICK Brown-Foxes jumped over the lazy dog's bone"
}

使用standard分词器进行分析

结果如下:

{
	"tokens": [
		{
			"token": "the",
			"start_offset": 0,
			"end_offset": 3,
			"type": "<ALPHANUM>",
			"position": 0
		},
		{
			"token": "2",
			"start_offset": 4,
			"end_offset": 5,
			"type": "<NUM>",
			"position": 1
		},
		{
			"token": "quick",
			"start_offset": 6,
			"end_offset": 11,
			"type": "<ALPHANUM>",
			"position": 2
		},
		{
			"token": "brown",
			"start_offset": 12,
			"end_offset": 17,
			"type": "<ALPHANUM>",
			"position": 3
		},
		{
			"token": "foxes",
			"start_offset": 18,
			"end_offset": 23,
			"type": "<ALPHANUM>",
			"position": 4
		},
		{
			"token": "jumped",
			"start_offset": 24,
			"end_offset": 30,
			"type": "<ALPHANUM>",
			"position": 5
		},
		{
			"token": "over",
			"start_offset": 31,
			"end_offset": 35,
			"type": "<ALPHANUM>",
			"position": 6
		},
		{
			"token": "the",
			"start_offset": 36,
			"end_offset": 39,
			"type": "<ALPHANUM>",
			"position": 7
		},
		{
			"token": "lazy",
			"start_offset": 40,
			"end_offset": 44,
			"type": "<ALPHANUM>",
			"position": 8
		},
		{
			"token": "dog's",
			"start_offset": 45,
			"end_offset": 50,
			"type": "<ALPHANUM>",
			"position": 9
		},
		{
			"token": "bone",
			"start_offset": 51,
			"end_offset": 55,
			"type": "<ALPHANUM>",
			"position": 10
		}
	]
}

可以看到文本经过 standard 分词器分词后,Token分别为:[ the, 2, quick, brown, foxes, jumped, over, the, lazy, dog’s, bone ]

我们也可以对 standard 进行如下特别配置:

  • max_token_length:可以指定Token的最大长度。
  • stopwords:配置停用词,默认缺省“none”。
  • stopwords_path:指定一个包含停用词的文件路径。

测试如下:
创建索引 my_standard_index

PUT http://127.0.0.1:9200/my_standard_index

{
  "settings": {
    "analysis": {
      "analyzer": {
        "my_english_analyzer": {
          "type": "standard",
          "max_token_length": 5,
          "stopwords": "_english_"
        }
      }
    }
  }
}

指定了token的最大长度为5;过滤停用符stopwords使用英文语言的。