前言
我们都知道,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使用英文语言的。