Elasticsearch查询命中文档_score恒为1.0 如何按指定字段权重算分
问题根因
所有命中文档得分固定为1.0是因为你错误放置了查询子句的位置,混淆了Elasticsearch的两种查询上下文:
- 查询上下文:子句会参与相关性
_score计算,匹配度越高、配置权重越高,文档最终得分越高,bool下的must、should子句默认属于该上下文 - 过滤上下文:子句仅判断文档是否匹配筛选规则,完全不参与得分计算,匹配结果还会被缓存提升查询性能,
bool下的filter、must_not子句属于该上下文
你当前的写法中,配置了字段权重的query_string全文检索被放在了filter块中,完全不参与算分;仅must块中var.keyword=sports的精确匹配属于查询上下文,所有符合该条件的文档在这个子句上的得分完全一致,最终就会出现所有返回结果得分都是1.0的情况。
修正方法
调整两个子句的位置即可:
- 把不需要参与算分的分类筛选(
var.keyword=sports)移到filter块,既保证只返回sports分类的文档,还能利用缓存提升查询效率 - 把需要按权重算分的
query_string检索移到must块,让它进入查询上下文,按照你配置的字段权重参与_score计算
修正后的DSL:
{ "query": { "bool": { "must": [ { "query_string": { "query": "sachin* OR messi", "fields": [ "name^1024", "description^32" ] } } ], "filter": [ { "term": { "var.keyword": "sports" } } ] } } }
预期效果
调整后返回的结果得分会符合你的权重预期:
- 命中
name字段的文档得分远高于仅命中description字段的文档(你配置的权重差为32倍) - 同字段下多词命中、完全匹配的文档得分高于单词命中、前缀匹配的文档
- 以你的测试数据为例,id=2的文档同时在
name、description字段命中messi,id=3的文档仅在name字段命中sachin前缀,两者得分会出现明显差异,不会再统一为1.0
内容的提问来源于stack exchange,提问作者sim
相关产品推荐
相关产品推荐

