1.先上结论,如下mapping可以解决es拼音排序问题
{
"settings": {
"number_of_shards": "3",
"number_of_replicas": "3",
"max_result_window": 100000,
"analysis": {
"analyzer": {
"pinyin_analyzer": {
"tokenizer": "pinyin_tokenizer"
}
},
"tokenizer": {
"pinyin_tokenizer": {
"type": "pinyin",
"keep_first_letter": true,
"keep_separate_first_letter": false,
"keep_full_pinyin": false,
"keep_original": false,
"limit_first_letter_length": 16,
"lowercase": false,
"remove_duplicated_term": false
}
}
}
},
"mappings": {
"properties": {
"columnA": {
"type": "keyword",
"fields": {
"ik": {
"type": "text",
"analyzer": "ik_max_word"
},
"pinyin": {
"type": "text",
"analyzer": "pinyin_analyzer",
"search_analyzer": "standard",
"fielddata": true
}
}
}
}
}
}
2.什么是analyzer?
简单来说analyzer包含3个部分
1.字符过滤器char_filter
2.分词器tokenizer
3.分词结果过滤器Token Filters
字符过滤器可以过滤一些HTML的特殊字符,分词器是我们对字段的分词规则的选择,包括常用的standard分词器,ik smart,ik max分词器,拼音分词器,分词结果过滤器用于对分词的结果 进行处理,比如大小写转换;
之前需要对某一个字段进行拼音的排序,但是失效了,失效的原因主要是如下几点:
1.拼音分词器无法处理多音字
2.拼音分词器默认的分词结果粒度太细 ,完成业务需要的粒度则需要最大
3.使用了icu分词器
主要处理的是第二点来最大程度满足业务需要,第三点弃用icu分词器
ps:为啥是最大程度,因为第一点es无法知道你是叫曾(zeng)志伟还是曾(ceng)志伟,这点无法解决;
我们需要研究拼音分词器的分词规则,采用某博主的对于拼音分词器的属性解释:
拼音分词属性简介
属性 说明
keep_first_letter 启用此选项时,例如:刘德华> ldh,默认值:true
keep_separate_first_letter 启用该选项时,将保留第一个字母分开,例如:刘德华> l,d,h,默认:false,注意:查询结果也许是太模糊,由于长期过频
limit_first_letter_length 设置first_letter结果的最大长度,默认值:16
keep_full_pinyin 当启用该选项,例如:刘德华> [ liu,de,hua],默认值:true
keep_joined_full_pinyin 当启用此选项时,例如:刘德华> [ liudehua],默认值:false
keep_none_chinese 在结果中保留非中文字母或数字,默认值:true
keep_none_chinese_together 保持非中国信一起,默认值:true,如:DJ音乐家- > DJ,yin,yue,jia,当设置为false,例如:DJ音乐家- > D,J,yin,yue,jia,注意:keep_none_chinese必须先启动
keep_none_chinese_in_first_letter 第一个字母保持非中文字母,例如:刘德华AT2016- > ldhat2016,默认值:true
keep_none_chinese_in_joined_full_pinyin 保留非中文字母加入完整拼音,例如:刘德华2016- > liudehua2016,默认:false
none_chinese_pinyin_tokenize 打破非中国信成单独的拼音项,如果他们拼音,默认值:true,如:liudehuaalibaba13zhuanghan- > liu,de,hua,a,li,ba,ba,13,zhuang,han,注意:keep_none_chinese和keep_none_chinese_together应首先启用
keep_original 当启用此选项时,也会保留原始输入,默认值:false
lowercase 小写非中文字母,默认值:true
trim_whitespace 默认值:true
remove_duplicated_term 当启用此选项时,将删除重复项以保存索引,例如:de的> de,默认值:false,注意:位置相关查询可能受影响
从上面 属性可以看出,keep_first_letter 启用此选项时,可以使得 拼音分词结果粒度最大,并能 实现我们的业务要求
至此,就完成拼音排序失效的问题
问题1:为什么拼音默认分词器的分词结果粒度太细 无法满足业务 要求?
先看dsl查询
GET /index/_search
{
"from": 12,
"size": 12,
"_source": "colunm",
"query": {
},
"sort": [
{
"colunm.pinyin": {
"order": "asc",
"mode":“min”,
"missing":"_last"
}
}
]
}
其中sort里面的mode的默认 值是min,指的是取分词结果的最小值,如果分词结果粒度 太细,那么将会把一个字段的多个分词的最小值 作为排序字段,所以,要将拼音分词器的分词结果粒度最大话,以使得将一个字段直接的拼音分词结果作为 排序字段