Elasticsearch query_string查询如何给匹配规则的文档加权提升排序
问题原因
你当前的boost没有生效,核心是第一个查询子句完全没有命中任何文档,加的权重根本没有起到作用:
你写的name:foo*bar*是要求name字段分词后的单个词元同时满足「以foo开头、以bar结尾」,但你的示例文档中foo和bar属于两个独立的分词(foos、bar是分开的两个词),所以这个子句没有命中任何文档。所有返回结果都只命中了第二个name:*foo*子句,得分完全一致,自然不会把带bar的文档排在前面。
修复方案
建议调整bool查询结构,把「必须包含foo」的逻辑放到must块保证过滤结果,把「优先返回带bar」的逻辑放到should块加权重,这样逻辑更清晰也更容易达到效果:
{ "query": { "bool": { "must": [ { "query_string": { "query": "name:*foo*" } } ], "should": [ { "query_string": { "query": "name:*bar*", "boost": 5 } } ], "minimum_should_match": 0 } } }
这个查询会先过滤出所有name带foo的文档,命中bar的文档会额外加上boost的权重,得分远高于只带foo的文档,自然会排在最前面。
优化建议
你当前用的前导通配符*foo*查询性能很差,会扫描所有倒排索引的词元,如果你的需求是匹配包含foo的完整词,直接用match查询性能会高很多:
{ "query": { "bool": { "must": [ { "match": { "name": "foo" } } ], "should": [ { "match": { "name": { "query": "bar", "boost": 5 } } } ] } } }
如果确实需要匹配词的一部分(比如foos要匹配foo),建议给name字段新增带ngram分词器的子字段,不用通配符也能实现模糊匹配,查询性能会提升数倍。
内容的提问来源于stack exchange,提问作者broun
相关产品推荐
相关产品推荐

