查询二次评分
Elasticsearch 二次评分(Rescore):优化顶部结果相关性
在 Elasticsearch 中,当基础查询返回的顶部文档相关性不够理想时,可通过二次评分(Rescore) 机制对前 N 个文档重新计算得分,进一步优化排序。这种方式既能保证查询效率(仅处理顶部文档),又能提升关键结果的准确性,适用于需要精细调整排序的场景(如搜索引擎结果页 Top 10 优化)。
二次评分的核心原理
二次评分的工作流程如下:
- 基础查询:执行初始查询(如
match、bool),获取匹配文档并按得分排序。 - 筛选顶部文档:从每个分片的结果中选取前
window_size个文档(默认取from + size个)。 - 重新评分:对这些顶部文档应用二次评分查询(如
function_score、script_score),计算新得分。 - 合并结果:根据配置的评分模式(如求和、相乘)合并原始得分与二次评分,得到最终排序。
基础语法与示例
基本结构
GET index/_search
{
"query": { // 1. 基础查询
"match": { "title": "elasticsearch" }
},
"rescore": { // 2. 二次评分配置
"window_size": 50, // 每个分片取前50个文档进行二次评分
"query": {
"rescore_query": { // 二次评分查询
"function_score": {
"script_score": {
"script": "doc['publishTime'].value / 1000000" // 以发布时间作为加分项
}
}
},
"query_weight": 0.8, // 原始得分权重
"rescore_query_weight": 0.2 // 二次评分权重
}
},
"size": 10 // 最终返回10条结果
}
得分计算逻辑
最终得分由原始查询得分和二次评分按权重合并:
最终得分 = (原始得分 × query_weight) + (二次评分 × rescore_query_weight)
- 示例中,原始得分占 80% 权重,二次评分(发布时间)占 20% 权重,使较新的文档排名更靠前。
核心参数详解
| 参数 | 作用 | 默认值 |
|---|---|---|
window_size |
每个分片参与二次评分的文档数量(过多会降低性能) | from + size(通常为 10) |
query_weight |
原始查询得分的权重系数 | 1.0 |
rescore_query_weight |
二次评分查询得分的权重系数 | 1.0 |
score_mode |
得分合并模式(total/multiply/avg/max/min) |
total(求和) |
示例:自定义得分合并模式
"rescore": {
"window_size": 30,
"query": {
"rescore_query": { "term": { "is_hot": true } }, // 对热门文档加分
"score_mode": "multiply" // 原始得分 × 二次评分(热门文档得分翻倍)
}
}
多阶段二次评分
对于更复杂的场景,可通过 rescore 数组实现多阶段二次评分(如先按内容相关性,再按热度,最后按时间):
GET articles/_search
{
"query": { "match": { "content": "AI 技术" } }, // 阶段1:内容匹配
"rescore": [
{ // 阶段2:热门文章加分
"window_size": 50,
"query": {
"rescore_query": { "term": { "is_hot": true } },
"rescore_query_weight": 0.3
}
},
{ // 阶段3:最新文章加分
"window_size": 20, // 对前20名进一步优化
"query": {
"rescore_query": {
"function_score": {
"script_score": { "script": "doc['publish_time'].value" }
}
},
"rescore_query_weight": 0.2
}
}
],
"size": 10
}
适用场景与最佳实践
1. 适用场景
- 顶部结果优化:基础查询返回的前 10~50 条结果相关性不足(如搜索引擎、推荐系统)。
- 多因素排序:需结合多个维度(内容匹配、热度、时间、用户行为)调整排序。
- 性能平衡:避免对所有文档应用复杂评分逻辑,仅优化顶部结果以节省资源。
2. 最佳实践
- 控制
window_size:取值不宜过大(建议 10~100),否则会抵消二次评分的性能优势。 - 权重合理分配:根据业务优先级调整
query_weight和rescore_query_weight(如内容匹配权重高于时间)。 - 避免复杂脚本:二次评分的
script应简洁(如字段值计算),复杂逻辑会增加计算开销。 - 结合过滤:先用
filter缩小范围,再对少量结果进行二次评分,提升效率。
与其他评分机制的对比
| 机制 | 特点 | 适用场景 |
|---|---|---|
| 二次评分(Rescore) | 仅对顶部文档重新评分,兼顾效率与精度 | 优化 Top N 结果相关性 |
function_score |
对所有匹配文档应用评分函数,功能强大但可能影响性能 | 全量文档的复杂评分逻辑 |
| 字段提升(Boost) | 对特定字段增加权重(如 title^2),适用于简单场景 |
基础字段优先级调整 |