一、概念:
分析器,用来对一段文字进行分析,经过分词,格式转化等一系列操作,最终生成倒排索引。分析器的选择直接影响到搜索效果,因为不同的分析器可能对同一个句子甚至同一个词折分出来的词是不相同的。经常有人称“分析器”为“分词器”,其实这种叫法是不准确的,因为分析器除了分词之处,还做了一些其他处理。分析器实际上是将三个功能封装在一起:
1、字符过滤器(Character Filters)
可以有多个字符过滤器,字符串按顺序通过每个字符过滤器,过滤器的任务是在分词前整理字符串。一个字符过滤器可以用来去掉HTML,或者将&转化成 `and`,可参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/analysis-charfilters.html;
2、分词器(Tokenizer)
字符串被分词器分为单个的词条。一个简单的分词器遇到空格和标点的时候,可能会将文本拆分成词条;至于具体应该怎么拆分,需要了解NLP领域的知识,可参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/analysis-tokenizers.html;
3、词元过滤器(Token Filters)
可以有多个词元过滤器,词条按顺序通过每个词元过滤器。这个过程可能会改变词条(比如转换大小写),删除词条(比如像`a`,`and`,`the`等无用词),词根提取(比如将复数形式转成单数形式),增加词条(比如增加同义词),可参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/analysis-tokenfilters.html。
当文档中的某个字段属性type被标识为“text”时,那么这个字段的文本就会被指定的分析器处理,如果未指定分析器,那么就使用默认的分析器进行处理。分析器对文本进行分析时,会对两种文本进行分析:
1、将要存储在es中的文本:也就是说,当某个字段的属性type被标识为“text”时,要存储到这个字段上的文本都会通过分析器得到处理,生成倒排索引。使用属性analyzer指定使用哪个分析器,如果不指定,则使用默认的分析器;
2、要查询的文本:也就是说,当某个字段的属性type被标识为“text”时,要在这个字段上查询某文本存不存在,那么这段要查询的文本就会通过分析器得到处理,生成的内容最终与es已生成的倒排索引进行匹配。使用属性search_analyzer指定使用哪个分析器,如果未指定search_analyzer属性,则会使用属性analyzer指定的分析器,如果analyzer属性也未指定,则使用默认的分析器。
默认分析器是settings中“default_search”定义的分析器,如果“default_search”未定义,则使用“default”定义的分析器,如果“default_search”和“default”都没有定义,则使用标准分析器(standard)。
一般情况下,存储文本和查询文本使用的分析器应该保持一致,这样才能保证对于相同的文本,存储到es时分析出来的词和查询条件分析出来的词是一样的,进而保持搜索效果。
二、常用分析器:
1、标准分析器(standard):内置分析器,根据Unicode联盟定义的单词边界划分文本,删除绝大部分标点,最后将词条小写。中文会拆成一个一个的单字;
2、简单分析器(simple):内置分析器,在任何不是字母的地方分割文本,最后将词条小写。遇中文不会分割,但遇数字会分割;
3、停用词分析器(stop):内置分析器,在简单分析器(simple)的基础上加入停用词,默认使用_english_停用词;
4、空格分析器(whitespace):内置分析器,在空格的地方划分文本,但不会将词条小写;
5、模式分析器(pattern):内置分析器,通过正则匹配分割文本;
6、特定语言分析器(language):内置分析器,根据指定语言的特点,对文本进行划分;
7、ik_smart分析器:ik中的一种分析器,会做最粗粒度的拆分,已被分出的词语将不会再次被其它词语占有,可以通过配置字典项指明哪些字组成的词可以不拆分,是汉语常用的分析器;
8、ik_max_word分析器:ik中的另一种分析器,会将文本做最细粒度的拆分,尽可能多的拆分出词语,已被分出的字可能被包含在多个词中,可以通过配置字典项指明哪些字组成的词可以不拆分,是汉语常用的分析器;
9、pinyin分析器:用户输入拼音就可以转化为对应的汉字,进行搜索内容;
由于同一个字段可能有不同的用处,所以在一个字段上支持使用多个不同的分析器,示例如下:
{
"title": {
"type": "text",
"analyzer": "ik_smart",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 64
},
"completion": {
"type": "completion",
"analyzer": "ik_max_word"
}
}
}
}
三、常用API:
1、自定义多个字符过滤器:
PUT http://$user:$passwd@$host:$port/$index
{
"settings": {
"analysis": {
"char_filter": {
"my_charfilter1": {
"type": "mapping",
"mappings": [
"& => and"
]
},
"my_charfilter2": {
"type": "pattern_replace",
"pattern": "(\\S+)-(\\S+)",
"replacement": "$1$2"
}
}
}
}
}
2、自定义多个分词器:
PUT http://$user:$passwd@$host:$port/$index
{
"settings": {
"analysis": {
"tokenizer": {
"my_tokenizer1": {
"type": "pattern",
"pattern": "\\s+"
},
"my_tokenizer2": {
"type": "pattern",
"pattern": "_"
}
}
}
}
}
3、自定义多个词元过滤器:
PUT http://$user:$passwd@$host:$port/$index
{
"settings": {
"analysis": {
"filter": {
"my_tokenfilter1": {
"type": "stop",
"stopwords": [
"the",
"a",
"an"
]
},
"my_tokenfilter2": {
"type": "stop",
"stopwords": [
"info",
"debug"
]
}
}
}
}
}
4、自定义多个分析器:
PUT http://$user:$passwd@$host:$port/$index
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer1": {
"char_filter": [
"html_strip",
"my_charfilter1"
],
"tokenizer": "my_tokenizer1",
"filter": [
"lowercase",
"my_tokenfilter1"
]
},
"my_analyzer2": {
"char_filter": [
"html_strip",
"my_charfilter2"
],
"tokenizer": "my_tokenizer2",
"filter": [
"my_tokenfilter2"
]
}
}
}
}
}
5、查看完整的分析器对内容分析的过程:
GET http://$user:$passwd@$host:$port/$index/_analyze
{
"char_filter" : ["html_strip"], //指定字符过滤器,可指定多个
"tokenizer": "standard", //指定分词器
"filter": [ "lowercase"], //指定词元过滤器,可指定多个
"text": 文本内容,
"explain" : true //是否展示分析过程
}
6、查看文本放入字段后的拆词结果:
GET http://$user:$passwd@$host:$port/$index/_analyze
{
"field": 字段名,
"text": 文本内容
}
7、查看文本经过分析器处理后的结果:
GET http://$user:$passwd@$host:$port/$index/_analyze
{
"analyzer": 分析器名,
"text": 文本内容
}
自定义分析器更多详情请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/analysis-custom-analyzer.html
分析器更多详情请参考:https://www.elastic.co/guide/en/elasticsearch/reference/6.5/analysis.html