真实配置两条独立的function_score加权规则,对比score_mode=sum精确累加权重与score_mode=max丢失多重命中信息的真实差异,验证不同业务语义下该如何正确选择score_mode。
代码真实索引4篇文档: 普通laptop / featured的laptop / on_sale的laptop / 两者都是的laptop POST /fs_test/_search {"query":{"function_score":{ "query":{"match":{"title":"laptop"}}, "functions":[ {"filter":{"term":{"featured":true}},"weight":2}, {"filter":{"term":{"on_sale":true}},"weight":3} ], "score_mode":"sum","boost_mode":"replace" }}}
score_mode=sum结果: → doc4 "laptop featured and on sale" score=5.0 ← 真实2+3=5,精确等于两个权重之和 → doc3 "laptop on sale" score=3.0 ← 真实只满足on_sale,权重3 → doc2 "laptop featured" score=2.0 ← 真实只满足featured,权重2 → doc1 "laptop basic" score=1.0 ← 真实两个条件都不满足
这组真实得分验证了score_mode:sum最直观的效果:每条functions规则真实独立判断自己的filter条件是否命中,命中了就把对应的weight计入总和,doc4真实同时命中了featured和on_sale两条规则,两个权重真实被完整地加在了一起变成5.0,精确反映出它"同时满足两个加分条件"这个事实。而boost_mode:replace真实让这个函数计算结果直接替代了原本的文本相关性得分,不再跟match查询的BM25分数做任何混合——这也是为什么doc1"laptop basic"这种完全没命中任何加分规则的文档,得分真实变成了1.0这个中性默认值,而不是它原本真实应该有的文本相关性分数。
代码同样的两条规则,只是把score_mode从sum换成max
score_mode=max结果: → doc3 "laptop on sale" score=3.0 ← 真实只满足on_sale,权重3 → doc4 "laptop featured and on sale" score=3.0 ← 真实同时满足两个条件,但得分跟doc3完全一样! → doc2 "laptop featured" score=2.0 → doc1 "laptop basic" score=1.0
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
function_score 查询与 score_mode 参数