Elasticsearch匹配短语前缀不匹配所有术语
Posted
技术标签:
【中文标题】Elasticsearch匹配短语前缀不匹配所有术语【英文标题】:Elasticsearch match phrase prefix not matching all terms 【发布时间】:2018-04-21 06:47:30 【问题描述】:我遇到了一个问题,当我在 Elasticsearch 中使用 match_phrase_prefix 查询时,它没有返回我期望的所有结果,尤其是当查询是一个单词后跟一个字母时。
采用这个索引映射(这是一个人为的保护敏感数据的例子):
http://localhost:9200/test/drinks/_mapping
返回:
"test":
"mappings":
"drinks":
"properties":
"name":
"type": "text"
在数以百万计的其他记录中,有这些:
"_index": "test",
"_type": "drinks",
"_id": "2",
"_score": 1,
"_source":
"name": "Johnnie Walker Black Label"
,
"_index": "test",
"_type": "drinks",
"_id": "1",
"_score": 1,
"_source":
"name": "Johnnie Walker Blue Label"
如下查询,即一个单词后两个字母:
POST http://localhost:9200/test/drinks/_search
"query":
"match_phrase_prefix" :
"name" : "Walker Bl"
返回这个:
"took": 1,
"timed_out": false,
"_shards":
"total": 5,
"successful": 5,
"failed": 0
,
"hits":
"total": 2,
"max_score": 0.5753642,
"hits": [
"_index": "test",
"_type": "drinks",
"_id": "2",
"_score": 0.5753642,
"_source":
"name": "Johnnie Walker Black Label"
,
"_index": "test",
"_type": "drinks",
"_id": "1",
"_score": 0.5753642,
"_source":
"name": "Johnnie Walker Blue Label"
]
而这个查询只有一个单词和一个字母:
POST http://localhost:9200/test/drinks/_search
"query":
"match_phrase_prefix" :
"name" : "Walker B"
不返回任何结果。这里会发生什么?
【问题讨论】:
【参考方案1】:我假设您正在使用 Elasticsearch 5.0 及更高版本。 我认为这可能是因为 max_expansions 默认值。
如文档here 中所见,max_expansions 参数用于控制最后一个术语将使用多少个前缀进行扩展。默认值为 50,这可以解释为什么您会发现“黑色”和“蓝色”的前两个字母 B 和 L,但不是只有 B。
文档很清楚:
match_phrase_prefix 查询是穷人的自动完成。它非常易于使用,可让您快速开始使用“键入即搜索”,但它的结果通常足够好,但有时可能会令人困惑。
考虑查询字符串 quick brown f。此查询通过创建一个由 quick 和 brown 组成的短语查询来工作(即,术语 quick 必须存在并且必须跟在术语 brown 之后)。然后它查看已排序的术语字典以查找以 f 开头的前 50 个术语,并将这些术语添加到短语查询中。
问题是前 50 个术语可能不包括术语 fox,因此不会找到 Phase quick brown fox。这通常不是问题,因为用户会继续输入更多字母,直到出现他们要查找的单词
如果您正在寻找良好的性能,我无法告诉您是否可以将此参数增加到 50 以上,因为我自己从未尝试过。
【讨论】:
一个问题,文档说它将寻找“快速”,然后是“棕色”。然后 elasticsearch 会查找以下 50 个(默认情况下)以“f”开头并按顺序以“quick”和“brown”开头的术语吗?或者只是任何以“f”开头的术语?在前面的任何情况下,如果至少有 2 个以(在这个问题中)“b”(“蓝色”和“黑色”)开头的术语我期待看到前 50 个术语,为什么不返回结果至少应该显示这两个或其他的。或者我错了。 也许这 50 个术语来自基于集群使用的语言的内置字典(因为 ES 支持自定义语言),而不是来自索引中的不同文档。这将解释为什么它是 match_phrase_prefix 查询的自定义参数,与仅使用“size”参数不同 就我而言,我的所有字段都没有映射上的语言属性。一旦我介绍了一封新信,结果就会显示得更准确。我正在使用 multi_match 查询"type": "phrase_prefix"
,所以不能使用 max_expansions
参数。
这似乎是个问题。 Index-time search-as-you-type 为我解决了这个问题:elastic.co/guide/en/elasticsearch/guide/current/…以上是关于Elasticsearch匹配短语前缀不匹配所有术语的主要内容,如果未能解决你的问题,请参考以下文章
Elasticsearch 8.X 有哪些自动补全的检索方式?
Elasticsearch 8.X 有哪些自动补全的检索方式?
Elasticsearch 8.X 有哪些自动补全的检索方式?
[Elasticsearch] 邻近匹配 - 短语匹配以及slop参数