问题
在工作中使用match_phrase_prefix语句进行搜索时,明明有满足条件的文档,但是却没有查询出来。具体操作步骤如下。
查询语句:
POST /tmproj/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"original": {
"query": "A Survey on Auto"
}
}
}
]
}
}
}
查询结果里面没有查询出目标文档:

调整查询语句,增加搜索条件中最后一个单词的长度:
POST /tmproj/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"original": {
"query": "A Survey on Autom"
}
}
}
]
}
}
}
查询出了目标文档:

与上一个查询条件相比,只是把搜索文本的最后一个单词由"Auto"变成了"Autom"
原因
第一反应是自己对match_phrase_prefix语句的使用方式产生了误解。
官网介绍
随即查看es官网:match_phrase_prefix官网介绍
发现一开始就有介绍:

即:返回包含所提供文本中指定词汇的文档,其排列顺序与所提供的顺序一致。所提供的文本中的最后一个词被视为前缀,用于匹配以该词开头的任何词汇。
备注
感觉自己没有理解错误,但是继续往下看发现了问题所在:

即:
虽然使用“match_phrase_prefix”查询进行搜索自动补全操作起来比较简便,但有时可能会产生令人困惑的结果。
例如,考虑查询字符串“quick brown f”。该查询的工作原理是将“quick”和“brown”组合成一个短语查询(即“quick”必须存在,并且必须紧接“brown”之后)。然后,它会查看已排序的词典,找出以“f”开头的前 50 个词,并将这些词添加到短语查询中。
问题在于前 50 个字符中可能不包含“fox”这个单词,所以“quick brown fox”这个短语是找不到的。但这种情况通常不会成为问题,因为用户会继续输入更多的字母,直到他们要查找的单词出现为止。
重要内容解释
重点分析一下这段话:
Then it looks at the sorted term dictionary to find the first 50 terms that begin with f, and adds these terms to the phrase query.
① looks at the sorted term dictionary
去排序后的词条词典里查找
什么是 sorted term dictionary?
它来自哪里?
这是 Lucene 底层索引结构,也就是:
ES 在建立索引时,对所有分词做过:
分词 → 去重 → 字典序排序 → 生成的词典表
例子:你的文档里有这些词:
fox
fan
food
face
family
fruit
...
ES 会把它们排序后变成:
face
family
fan
food
fox
fruit
...
这张排好序的单词表,就是
sorted term dictionary
它存在于磁盘的 Lucene 索引文件中。
② to find the first 50 terms that begin with f
找到字典序里【最前面的 50 个】以 f 开头的词
重点:
不是找所有匹配的!
而是只取前 50 个!
默认 max_expansions = 50
③ and adds these terms to the phrase query
翻译:
把这 50 个词,加入到短语查询中
也就是说:
quick brown + [fan / face / food / ... 50个词]
ES 只会去匹配:
quick brown fan
quick brown face
quick brown food
...
它不会去匹配其它词!
最关键一句:
The problem is that the first 50 terms may not include the term fox
翻译:
问题在于:前 50 个词里,可能不包含 fox!
例子:
排序后的词典:
1. face
2. family
3. fan
4. far
5. fat
6. favor
...
50. fly
51. fox
fox 排在第 51 位以后!
就会出现明明存在,但查不到!
解决
从官网介绍也可以看出,解决办法有两种
增大max_expansions参数的值
调整max_expansions参数后(经过试验,我的案例需要调整到94),可以查询到目标文档。
POST /tmproj/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"original": {
"query": "A Survey on Auto",
"max_expansions": 94
}
}
}
]
}
}
}
多输入搜索文本字母
即不断增加查询文本的长度,我的案例是将最后一个单词由"Auto"调整为"Autom"后即可查询出目标文档。
POST /tmproj/_search
{
"query": {
"bool": {
"must": [
{
"match_phrase_prefix": {
"original": {
"query": "A Survey on Autom"
}
}
}
]
}
}
}
总结
match_phrase_prefix 工作原理:
-
前面所有词 = 短语精确匹配
-
最后一个词 = 去词典查前缀
-
只取前 50 个(max_expansions=50)
-
把这 50 个词拼回短语查询
-
如果你的词不在这 50 个里 → 查不到!

1995

被折叠的 条评论
为什么被折叠?



