Elasticsearch 不管是索引任务还是搜索工作,都需要经过 es 的 analyzer(分析器),至于分析器,它分为内置分析器和自定义的分析器。分析器进一步由字符过滤器(Character Filters)、分词器(Tokenizer)和词元过滤器(Token Filters)三部分组成。
组成
如上所述,分析组件由如下三部分组成,它的执行顺序如下:
character filters -> tokenizer -> token filters
Character Filters
character filter 的输入是原始的文本 text,如果配置了多个,它会按照配置的顺序执行,目前 es 自带的 character filter 主要由如下 3 类:
- HTML strip character filter:从文本中剥离 HTML 元素,并用其解码值替换 HTML 实体(如,将
&
替换为&
)。 - Mapping character filter:自定义一个 map 映射,可以进行一些自定义的替换,如常用的大写变小写也可以在该环节设置。
- Pattern Replace character filter:使用 java 正则表达式来匹配应替换为指定替换字符串的字符,此外,替换字符串可以引用正则表达式中的捕获组。
HTML strip 如下示例:
GET /_analyze
{
"tokenizer": "keyword",
"char_filter": [
"html_strip"
],
"text": "<p>I'm so <b>happy</b>!</p>"
}
经过 html_strip
字符过滤器处理后,输出如下:
[ \nI'm so happy!\n ]
Mapping character filter 接收键和值映射(key => value)作为配置参数,每当在预处理过程中遇到与键值映射中的键相同的字符串时,就会使用该键对应的值去替换它。
原始文本中的字符串和键值映射中的键的匹配是贪心的,在对给定的文本进行预处理过程中如果配置的键值映射存在包含关系,会优先匹配最长键。同样也可以用空字符串进行替换。
mapping char_filter 不像 html_strip 那样拆箱即可用,必须先进行配置才能使用,它有两个属性可以配置:
参数名称 | 参数说明 |
---|---|
mappings |
一组映射,每个元素的格式为 key => value。 |
mappings_path |
一个相对或者绝对的文件路径,指向一个每行包含一个 key =>value 映射的 UTF-8 编码文本映射文件。 |
mapping char_filter 示例如下:
GET /_analyze
{
"tokenizer": "keyword",
"char_filter": [
{
"type": "mapping",
"mappings": [
"٠ => 0",
"١ => 1",
"٢ => 2",
"٣ => 3",
"٤ => 4",
"٥ => 5",
"٦ => 6",
"٧ => 7",
"٨ => 8",
"٩ => 9"
]
}
],
"text": "My license plate is ٢٥٠١٥"
}
分析结果如下:
[ My license plate is 25015 ]
Pattern Replace character filter 支持如下三个参数:
参数名称 | 参数说明 |
---|---|
pattern |
必填参数,一个 java 的正则表达式。 |
replacement |
替换字符串,可以使用 $1 ... $9 语法来引用捕获组。 |
flags |
Java 正则表达式的标志,具体参考 java 的 java.util.regex.Pattern 类的标志属性。 |
如将输入的 text 中大于一个的空格都转变为一个空格,在 settings 时,配置示例如下:
"char_filter": {
"multi_space_2_one": {
"pattern": "[ ]+",
"type": "pattern_replace",
"replacement": " "
},
...
}
tokenizer
tokenizer 即分词器,也是 analyzer 最重要的组件,它对文本进行分词;一个 analyzer 必需且只可包含一个 tokenizer。
es 自带默认的分词器是 standard tokenizer,标准分词器提供基于语法的分词(基于 Unicode 文本分割算法),并且适用于大多数语言。
此外有很多第三方的分词插件,如中文分词界最经典的 ik 分词器,它对应的 tokenizer 分为 ik_smart 和 ik_max_word,一个是智能分词(针对搜索侧),一个是全切分词(针对索引侧)。
token filters
token filters 叫词元过滤器,或词项过滤器,对 tokenizer 分出的词进行过滤处理。常用的有转小写、停用词处理、同义词处理等等。一个 analyzer 可包含0个或多个词项过滤器,按配置顺序进行过滤。
以同义词过滤器的使用示例,具体如下:
PUT /test_index
{
"settings": {
"index": {
"analysis": {
"analyzer": {
"synonym": {
"tokenizer": "standard",
"filter": [ "my_stop", "synonym" ]
}
},
"filter": {
"my_stop": {
"type": "stop",
"stopwords": [ "bar" ]
},
"synonym": {
"type": "synonym",
"lenient": true,
"synonyms": [ "foo, bar => baz" ]
}
}
}
}
}
}