Elasticsearch 相关性控制的艺术

文章介绍了Elasticsearch中控制搜索结果相关性的三种方法:boosting查询可降低匹配负面条件文档的得分;function_score通过综合浏览量、评论数等指标调整排名;rescore查询则对初步结果进行二次打分以优化性能。这些方法能帮助提升搜索结果的精准度。

作品集: Elastic Stack
作者头像
LumiBee
15 天前 · 105 1
分享

Elasticsearch 相关性控制的艺术

我们可以通过控制相关性的得分使得用户最想要的结果排在最前面。本文所举的例子依旧是建设博客的搜索引擎。

1. boosting 查询

它允许我们为一个查询指定的一个“正面”条件和一个“负面”条件,匹配到负面条件的文档,其相关性得分会按照比例降低

需求:搜索“Elasticsearch”,但如果文章标签中包含“过时”,则降低其排名

GET /blog_posts/_search  
{  
  "query": {  
    "boosting": {  
      "positive": { "match": { "content": "Elasticsearch" } },  
      "negative": { "term":  { "tags": "过时" } },  
      "negative_boost": 0.2 // 负面匹配的文档,得分将乘以 0.2  
    }  
  }  
}

2. function_score

这是最强大的相关性控制工具,允许我们用一个或多个函数来修改原始查询的 _score。

需求:搜索“Java”,并综合考虑浏览量,评论数,点赞数和发布时间来决定最终排名

GET /blog_posts/_search  
{  
  "query": {  
    "function_score": {  
      "query": { "match": { "content": "Java" } },  
      "functions": [  
        { "filter": { "range": { "view_count": { "gte": 1000 } } }, "weight": 1.5 }, // 浏览量过千,权重乘以1.5  
        { "field_value_factor": { "field": "comment_count", "modifier": "log1p", "factor": 0.5 } }, // 评论数越多得分越高  
        { "field_value_factor": { "field": "likes", "modifier": "log1p", "factor": 0.3 } }, // 点赞越多得分越高 
        { "gauss": { "publish_date": { "origin": "now", "scale": "90d", "decay": 0.5 } } } // 离现在越近得分越高  
      ],  
      "score_mode": "sum",   // 将所有函数得分与原始得分相加  
      "boost_mode": "multiply" // 将最终计算出的函数总分与原始得分相乘  
    }  
  }  
}
  • "modifier": "log1p":这是平滑处理的关键。直接用评论数(比如10000)可能会导致分数过高,压倒其他因素。log1p 函数(计算 log(1 + x))可以削弱极端值的影响,使得评论数从10增加到100带来的分数提升,远大于从10000增加到10100带来的提升。这更符合“边际效益递减”的直觉。
  • "gauss"(高斯衰减函数):这是一个“时效性/距离衰减器”。它根据一个数值或日期字段的值与一个“中心点”的接近程度来打分。
    • "origin": "now":设置“中心点”为当前时间,如果发布日期就是今天,得分就会最高为1。
    • "scale": "90d"定义了衰减的速率。它设定了一个关键的校准点:当文章的发布日期距离现在达到90天时,它的时效性得分会正好衰减为下面 decay 定义的值
    • "decay": 0.5:定义衰减率。当距离达到 scale(90天)时,分数会衰减为 decay 的值,即 0.5。
  • "score_mode": 决定如何将 functions 数组中每个函数独立计算出的分数合并成一个总的函数分,可选模式:
    • sum (求和):总函数分 = 分数1 + 分数2 + 分数3
    • multiply (求积):总函数分 = 分数1 * 分数2 * 分数3
    • avg (平均值)、max (最大值)、min (最小值)
  • "boost_mode":决定如何将上一步计算出的**“总函数分”应用到第一步得到的“原始 _score”**上,从而得到最终排名分,可选模式:
    • multiply (相乘):最终分 = 原始 _score * 总函数分。这是最常用的,因为它能让函数分作为原始相关性的一个“增强系数”
    • sum (相加):最终分 = 原始 _score + 总函数分
    • replace (替换):最终分 = 总函数分 (完全忽略原始的 _score)
    • avg, max, min

3. rescore 查询

当我们有一个计算开销非常大的排序逻辑时,rescore 是最佳选择。它只对第一阶段查询返回的 top N 个结果,进行第二次、更复杂的打分。

需求:先快速地从百万篇文章中找出包含“性能优化”的 100 篇文章,然后只对这 100 篇文章,运行一个复杂的、基于脚本的业务排序逻辑。

GET /blog_posts/_search  
{  
  "query": { "match": { "content": "性能优化" } },  
  "rescore": {  
    "window_size": 100, // 只对前100个结果进行二次打分  
    "query": {  
      "rescore_query": {  
        "function_score": { // 在这里使用复杂的 function_score  
          // ... 一个计算开销很大的函数 ...  
        }  
      }  
    }  
  }  
}
阅读量: 105

评论区

登录后发表评论

正在加载评论...
相关阅读

Elasticsearch 入门指南

# Elasticsearch 入门指南:从零到一构建搜索引擎 在成功部署了 Elasticsearch 和 Kibana 后,如果还有不会安装的可以查看这篇[文章](https://hive...

164
1

Redis04_数据类型

# 五大数据类型 ![image-20250506173728272](https://p.ipic.vip/iq69f6.png) ## Redis-Key ```bash 127.0....

81
0

MyBatis-Plus讲解

# 介绍 ​ [MyBatis-Plus](https://github.com/baomidou/mybatis-plus) 是一个 [MyBatis](https://www.mybati...

139
0

Elasticsearch 关联关系处理指南

# **Elasticsearch 关联关系处理指南** 当我们将数据从 MySQL 等关系型数据库迁移到 Elasticsearch 时,遇到的第一个挑战往往就是如何处理表与表之间的关联关系...

81
0

一个草稿箱功能的实现

# **从零到一:一个“自动保存草稿”功能的实现** 在现代Web应用中,用户体验至上。没有什么比用户在精心编辑长篇内容后,因意外关闭浏览器或网络问题而丢失所有心血更令人沮丧的了(一位站友就...

121
1

Spring Security实战-构建安全的Web应用

Spring Security 作为 Spring 生态系统中不可或缺的一员,提供了一套全面且可扩展的机制来处理身份验证和授权。本文将结合实际应用场景,深入剖析 Spring Security ...

123
0