一、问题描述
用一句话总结问题便是:使用ik分词器,“长”关键字wildcard搜索不到数据。
POST /lpm-company-dev/_search
{
"query":{
"bool" : {
"must" : [
{
"bool" : {
"should" : [
{
"wildcard" : {
"name" : {
"wildcard" : "*鸿运*",
"boost" : 1.0
}
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
}
关键词为“鸿运”可以搜索到数据,但是“鸿运物流”却搜索不到。
二、问题分析
mapping分词器设置
"name": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
}
分析
ik_max_word
解析结果:
POST /lpm-company-dev/_analyze
{
"text": [
"阜阳市鸿运物流有限公司"
],
"analyzer": "ik_max_word"
}
分析结果:
{
"tokens" : [
{
"token" : "阜阳市",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "阜阳",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "市",
"start_offset" : 2,
"end_offset" : 3,
"type" : "CN_CHAR",
"position" : 2
},
{
"token" : "鸿运",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "物流",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "有限公司",
"start_offset" : 7,
"end_offset" : 11,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "有限",
"start_offset" : 7,
"end_offset" : 9,
"type" : "CN_WORD",
"position" : 6
},
{
"token" : "公司",
"start_offset" : 9,
"end_offset" : 11,
"type" : "CN_WORD",
"position" : 7
}
]
}
ik_smart
解析结果:
POST /lpm-company-dev/_analyze
{
"text": [
"阜阳市鸿运物流有限公司"
],
"analyzer": "ik_smart"
}
{
"tokens" : [
{
"token" : "阜阳市",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "鸿运",
"start_offset" : 3,
"end_offset" : 5,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "物流",
"start_offset" : 5,
"end_offset" : 7,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "有限公司",
"start_offset" : 7,
"end_offset" : 11,
"type" : "CN_WORD",
"position" : 3
}
]
}
三、猜想
ik分词之后,wildcard就不能正常使用了?目前经过测试,答案正是如此;我们又没有太多的精力来维护ik分词器的词典。
修改属性配置
于是重建索引,不再使用ik分词器,关键字段设置为:
"name": {
"type": "text",
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
使用ik分词器时,是看不到name.keyword属性的;默认分词器才会有。
重建索引后测试,wildcard可以正常使用了。
POST /lpm-company-dev/_search
{
"query":{
"bool" : {
"must" : [
{
"bool" : {
"should" : [
{
"wildcard" : {
"name.keyword": {
"wildcard" : "*鸿运物流*",
"boost" : 1.0
}
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
],
"adjust_pure_negative" : true,
"boost" : 1.0
}
}
}
四、总结
本总结以搜索name属性为例。
- 搜索字段为中文时,使用ik分词器会影响wildcard搜索,搜索属性为“name”,且无
name.keyword
属性。 - 搜索字段为中文时,使用默认分词器时wildcard可以正常搜索,搜索属性应为
name.keyword
; - 搜索字段为数字或英文构成的字符串时,搜索属性可以使用
name
或name.keyword
。
遗留问题
上述最终解决方法是没有再使用ik分词器匹配,如有朋友们有更好的方案,欢迎留下您的脚印👣👣~
主要纠结的点在于:
1、不想自己维护词典,ik分词器的字典更新后需要es重启;
2、ik分词和wildcard查询的相互影响怎么避免?