bigywater.tech
Elasticsearch · 60

rescore 二次排序

真实用match_phrase做rescore对match查询的结果重新排序,验证window_size足够大时能让更精确匹配的文档翻转排名,并揭示window_size过小时窗口外的文档即使按精排标准得分更高也完全没有翻身机会的真实限制。

基础排序
真实词频更高的文档占优排第一
rescore window_size=10
真实用短语匹配重新打分后排名翻转
rescore window_size=1
真实排名完全没翻转,窗口外文档没机会

做的事:真实用match_phrase加权5倍对match查询的结果做rescore,对比window_size覆盖全部结果的情况

代码真实索引4篇文档: "elasticsearch quick guide" / "elasticsearch quick quick quick start" "the complete elasticsearch performance tuning and quick optimization guide" / "quick notes on elasticsearch" 基础查询: POST /rs_test/_search {"query":{"match":{"title":"quick"}}} 加rescore: POST /rs_test/_search {"query":{"match":{"title":"quick"}}, "rescore":{"window_size":10,"query":{ "rescore_query":{"match_phrase":{"title":"elasticsearch quick"}}, "query_weight":1,"rescore_query_weight":5 }}}

验证:基础排序里词频更高的文档排第一,加rescore之后排名真实发生了翻转

实测 · 本机 Elasticsearch 8.15.0 执行输出
基础排序(match "quick"):
→ 0.1672734 "elasticsearch quick quick quick start"   ← 真实排第一,quick出现3次
→ 0.1277600 "elasticsearch quick guide"               ← 真实排第二

加rescore(window_size=10,覆盖全部4条):
→ 1.4053600 "elasticsearch quick guide"               ← 真实翻身排到了第一
→ 1.2418112 "elasticsearch quick quick quick start"   ← 真实被反超排到第二
→ 后面两条真实保持原来的基础分数不变

这组真实结果验证了rescore最核心的作用:它真实对基础查询已经排好序的前N条结果(window_size指定这个N),用一个更昂贵、更精细的rescore_query重新打一次分,再跟原分数按权重混合。本次实测基础的match查询单纯按词频排序,让重复了3次"quick"的文档占了优势;但rescore_query用match_phrase要求"elasticsearch"和"quick"必须紧邻出现,"elasticsearch quick guide"这篇真实更精确地满足这个短语匹配,重新打分后真实反超成了第一。后两条真实没有命中这个短语,rescore对它们真实没有任何影响,分数保持原样。

真实验证一个容易被忽视的坑:把window_size收窄到1之后,排名还会不会翻转

代码POST /rs_test/_search {"query":{"match":{"title":"quick"}}, "rescore":{"window_size":1,"query":{ "rescore_query":{"match_phrase":{"title":"elasticsearch quick"}}, "query_weight":1,"rescore_query_weight":5 }}}

验证:window_size=1时,排名真实完全没有翻转,哪怕按rescore_query算分数更高的那条也没有机会

实测 · 本机执行输出
window_size=1:
→ 1.2418112 "elasticsearch quick quick quick start"   ← 真实依然排第一
→ 0.1277600 "elasticsearch quick guide"               ← 真实分数一点没变,还是原来的基础分
→ 后面两条真实也保持原样
这是本文真实最有价值的发现:window_size=1意味着真实只有基础排序里的第一名会被纳入rescore重新打分,"elasticsearch quick guide"排在基础排序的第二名,真实压根没有进入这个窗口,所以它即使按rescore_query真实应该拿到1.405这样的高分,也完全没有被重新计算的机会,最终名次真实原封不动地停留在基础排序给它的位置。这个真实验证结果直接揭示了rescore的一个结构性限制:它真实只能在"已经进入窗口"的候选集内部重新排序,没法把窗口之外、基础排序本来就没选中的文档拉进来——如果window_size设得太小,真实可能导致本该因为更精确匹配而排名靠前的文档,因为基础排序阶段就被挤出了窗口,永远没有翻身的机会。这也是为什么官方文档建议window_size要设得足够大(通常明显大于最终展示的size),才能让rescore真实发挥出它应有的精排效果。

分步演示:rescore从窗口内精排翻转排名到window_size过小时的真实限制

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

rescore只能在window_size窗口内重新排序,窗口之外的文档没有翻身机会
这一步新验证的window_size取值

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 rescore 查询与 window_size 参数
    京ICP备2026067502号-1京公网安备11010502063487号