愚者求师之过,智者从师之长。

ik分词情况下“中国人民银行”为例,无法命中结果?

Elasticsearch | 作者 jingkyks | 发布于2017年08月11日 | 阅读数:6854

doc内容:
{"content":"中国人民银行"} 
ik_max_word分词。
分词结果如下:
"tokens" : [
{
"token" : "中国人民银行",
"start_offset" : 0,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 0
},
{
"token" : "中国人民",
"start_offset" : 0,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 1
},
{
"token" : "中国人",
"start_offset" : 0,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 2
},
{
"token" : "中国",
"start_offset" : 0,
"end_offset" : 2,
"type" : "CN_WORD",
"position" : 3
},
{
"token" : "国人",
"start_offset" : 1,
"end_offset" : 3,
"type" : "CN_WORD",
"position" : 4
},
{
"token" : "人民银行",
"start_offset" : 2,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 5
},
{
"token" : "人民",
"start_offset" : 2,
"end_offset" : 4,
"type" : "CN_WORD",
"position" : 6
},
{
"token" : "银行",
"start_offset" : 4,
"end_offset" : 6,
"type" : "CN_WORD",
"position" : 7
}
]
查询条件如下:
curl -XGET 'localhost:9200/chineseindex/_search?pretty' -d '{"explain":true,"query":{"query_string":{"fields":["content"],"query":"\"中国人 中国\""}}}'
查询词加了引号。"中国人"和“中国”的position一个是2,一个是3.应该是可以命中。事实是并不命中。
查询时,采用ik_max_word分词,会产生两个"中国"词。
即使使用了 "中国人 中国"~5 仍然不能命中。
如果指定查询时分词为ik_smart如下:
curl -XGET 'localhost:9200/chineseindex/_search?pretty' -d '{"query":{"query_string":{"fields":["content"],"query":"\"中国人 中国\"", "analyzer":"ik_smart"}}}'
这样可以命中。
 
这是什么原因?
 
已邀请:

medcl - 今晚打老虎。

赞同来自: rockybean lz8086 jingkyks fishyou

1.不同的分词会产生不同的分词结果,max_word产生的词位置有重叠;smart不会有位置重叠;
2.查询条件加引号,查询处理的时候,会将引号内的查询关键字作为一个整体,重写为 phrase 查询;
  • 索引:中国人民银行 -> 中国人民银行 中国人民 中国人 中国 国人人民银行 人民 银行 银 行
  • 查询:"\"中国人 中国\""-> "中国人 中国 国人 中国" ,是一个Phrase查询。

 
关键点在于查询展开之后,附加了一个“中国”,这个中国是带有位置属性的(phrase),而在索引里面,是没有两个“中国”的,即需要保证先出现一个“中国人”,然后“中国”,再出现一个“国人”,再出现一个“中国”,所以命中不了,有 4 个term要出现,且满足一个大概的位置,当然,可以通过 slop 设置位置的跳跃。
 
你要是把索引数据改成:“中国人民银行 中国”,就能查出来。
  
 

lz8086 - es小司机

赞同来自: AlixMu fishyou

所以query_string对查询内容默认的分词是该字段mapping中所设置的分词喽,要是
GET /_search
{
"query": {
"query_string" : {
"fields" : ["content", "name"],
"query" : "this AND that"
}
}
}
这种情况, content与name分别采用A、B分词,
(content:this OR name:this) AND (content:that OR name:that)
AND前面语句会先把this按照A、B分词后在匹配content和name喽,AND后面亦然,是否是这样呢?
然后那么对_all字段查询时默认的分词又是什么呢?
谢谢解惑。@medcl

laoyang360 - 《一本书讲透Elasticsearch》作者,Elastic认证工程师 [死磕Elasitcsearch]知识星球地址:http://t.cn/RmwM3N9;微信公众号:铭毅天下; 博客:https://elastic.blog.csdn.net

赞同来自:

确认你数据类型是text了吗??

lz8086 - es小司机

赞同来自:

把 "query":"\"中国人 中国\""  改为 "query":"中国人 中国"   试试

luggie

赞同来自:

请问你的es装了x-pack吗

要回复问题请先登录注册