当前位置: 首页 > news >正文

【Elasticsearch】自定义评分检索

在这里插入图片描述

自定义评分检索

  • 1.自定义评分
  • 2.为什么需要自定义评分
  • 3.搜索结果相关度
  • 4.影响相关度评分的查询子句
  • 5.控制相关度评分的方法
    • 5.1 Function Score Query
      • 5.1.1 基础查询部分
      • 5.1.2 评分函数部分(functions 数组)
        • 第一个函数:品牌加权
        • 第二个函数:销量因子
        • 第三个函数:时间衰减
      • 5.1.3 评分组合方式
        • score_mode
        • boost_mode
      • 5.1.4 整体效果
    • 5.2 使用 Boosting Query
      • 5.2.1 正向查询(positive)
      • 5.2.2 负向查询(negative)
      • 5.2.3 降权系数(negative_boost)
      • 5.3.4 工作流程
      • 5.2.5 与 bool 查询的区别
      • 5.2.6 典型应用场景
      • 5.2.7 参数注意事项
      • 5.2.8 性能考虑
    • 5.3 使用 Script Score
  • 6.相关度评分控制技巧

1.自定义评分

自定义评分Score Customization)是指通过编程方式修改或覆盖 Elasticsearch 默认的相关度评分算法,以满足特定业务需求的过程。

Elasticsearch 默认使用 TF-IDF(在较新版本中使用 BM25)算法计算文档相关性,但有时业务需求需要特殊的排序逻辑。

🚀 建议先看一下我的这几篇博文:

  • 【自然语言处理】文本表示:One-Hot、BOW、TF-IDF、N-Gram
  • 【自然语言处理】BOW 和 TF-IDF 详解
  • 【自然语言处理】文本相似度算法:TF-IDF 与 BM25

2.为什么需要自定义评分

  • 业务特定需求:默认评分可能无法准确反映业务领域的相关性标准。
  • 个性化排序:根据用户偏好、地理位置、时间敏感性等因素调整结果。
  • 商业逻辑:如提升付费内容、促销商品的排名。
  • 多维度排序:结合相关性、销量、评分、新鲜度等多个因素。
  • 领域专业知识:某些领域有独特的价值评估标准。

3.搜索结果相关度

  • 相关度_score)是 Elasticsearch 判断文档与查询匹配程度的量化值。
  • 自定义评分 不是替代相关度计算,而是在其基础上进行 调整或补充
  • 最终排序可以结合默认相关度和自定义评分因素。

4.影响相关度评分的查询子句

  • 全文检索查询matchmatch_phrasemulti_matchquery_string
  • 词项级别查询term(通常不评分,但可通过参数启用)、termsfuzzy
  • 复合查询boolmust / should)、dis_maxconstant_score
  • 特殊查询boostingfunction_scorescript_score
  • 查询参数boost(可应用于任何查询)、tie_breaker(在 dis_max 中使用)

filtermust_not 被视为过滤器,不影响评分。其他查询子句会影响评分。

5.控制相关度评分的方法

接下来,我们就介绍一下 boostingfunction_scorescript_score 这几个特殊查询是如何影响评分的。

5.1 Function Score Query

{"query": {"function_score": {"query": { "match": { "title": "手机" } },"functions": [{"filter": { "term": { "brand": "苹果" } },"weight": 2},{"field_value_factor": {"field": "sales","modifier": "log1p","factor": 0.1}},{"gauss": {"date": {"origin": "now","scale": "30d","offset": "7d","decay": 0.5}}}],"score_mode": "sum","boost_mode": "multiply"}}
}

这段代码是一个 Elasticsearch 的 function_score 查询,用于对基础查询结果进行自定义评分调整。这是一个复合查询,主要包含:

  • 基础查询(match 查询)
  • 多个评分函数(functions 数组)
  • 评分组合方式(score_modeboost_mode

5.1.1 基础查询部分

"query": { "match": { "title": "手机" } }
  • 这是基础查询,查找 title 字段包含 “手机” 的文档。
  • 这部分会先执行,产生初始的相关性评分(_score)。

5.1.2 评分函数部分(functions 数组)

第一个函数:品牌加权
{"filter": { "term": { "brand": "苹果" } },"weight": 2
}
  • 作用:对品牌为 “苹果” 的文档应用权重。
  • 机制
    • 先过滤出 brand 字段精确匹配 “苹果” 的文档。
    • 为这些文档的评分乘以权重因子 2。
  • 效果:苹果品牌的产品会获得更高的排名。
第二个函数:销量因子
{"field_value_factor": {"field": "sales","modifier": "log1p","factor": 0.1}
}
  • 作用:根据销量(sales 字段)调整评分。
  • 参数
    • field:使用 sales 字段的值。
    • modifier:应用 log1p 函数(即 log(1 + sales)),防止极高销量值对评分影响过大。
    • factor:乘以 0.1 的因子,减小影响程度。
  • 效果:销量高的产品会获得一定提升,但不会完全主导排序。
第三个函数:时间衰减
{"gauss": {"date": {"origin": "now","scale": "30d","offset": "7d","decay": 0.5}}
}
  • 作用:基于日期字段(date)实现时间衰减评分。
  • 高斯衰减参数
    • origin:当前时间("now")作为基准点。
    • scale:衰减范围为 30 30 30 天。
    • offset 7 7 7 天内不衰减,保持完整评分。
    • decay:衰减到 0.5 0.5 0.5(在 origin + offset + scale 时,得分为 0.5*原始分)。
  • 效果:较新的文档会获得更高评分,但 7 7 7 天内无差别,之后逐渐衰减。

5.1.3 评分组合方式

score_mode
"score_mode": "sum"
  • 指定多个函数评分如何组合
  • sum 表示将所有函数评分相加。
  • 其他可选值:multiply)、avg平均)、max最大)、min最小)、first第一个函数)。
boost_mode
"boost_mode": "multiply"
  • 指定函数评分如何与原始查询评分组合
  • multiply 表示将函数评分与原始 _score 相乘。
  • 其他可选值:replace替换)、sum相加)、avg平均)、max最大)、min最小)。

5.1.4 整体效果

这个查询会:

  • 首先找出所有标题包含 “手机” 的文档。
  • 然后对这些文档进行评分调整:
    • 如果是 苹果 品牌,评分 ×2
    • 根据销量(取对数后)增加评分。
    • 根据时间远近衰减评分(越新评分越高)。
  • 将所有函数评分相加(score_mode: sum)。
  • 最后将总函数评分与原始评分相乘(boost_mode: multiply)。
  • 按最终评分排序返回结果。

这种查询非常适合电商搜索场景,可以同时考虑关键词相关性、品牌偏好、销量热度和新品时效性。

5.2 使用 Boosting Query

{"query": {"boosting": {"positive": { "match": { "title": "手机" } },"negative": { "term": { "brand": "山寨" } },"negative_boost": 0.2}}
}

这段代码使用了 Elasticsearch 的 boosting 查询,它是一种特殊的复合查询,用于对匹配某些条件的文档进行降权而非完全排除。下面我将详细解释每个部分的含义和作用:

  • positive:正向查询(必须匹配)
  • negative:负向查询(匹配则降权)
  • negative_boost:降权系数

5.2.1 正向查询(positive)

"positive": { "match": { "title": "手机" } }
  • 这是一个标准的全文匹配查询。
  • 会找出所有 title 字段包含 “手机” 的文档。
  • 这些文档都会被包含在最终结果中(如果不匹配 negative 条件则保持原评分)。

5.2.2 负向查询(negative)

"negative": { "term": { "brand": "山寨" } }
  • 这是一个精确匹配查询(term query)。
  • 会找出 brand 字段精确等于 “山寨” 的文档。
  • 匹配 negative 查询的文档不会被排除,而是会被降权

5.2.3 降权系数(negative_boost)

"negative_boost": 0.2
  • 这是一个介于 0 0 0 1 1 1 之间的乘数因子。
  • 对于 同时匹配 positive 和 negative 的文档:
    • 最终评分 = 原始评分 × 0.2
  • 对于 只匹配 positive 的文档:
    • 保持原始评分不变

5.3.4 工作流程

  • 首先执行 positive 查询,找出所有标题包含 “手机” 的文档。
  • 然后在这些文档中,找出品牌为 “山寨” 的文档。
  • 对匹配 negative 条件的文档,将其评分乘以 0.2
  • 最后按调整后的评分排序返回结果。

5.2.5 与 bool 查询的区别

特性
boosting 查询
bool 查询( must_not
匹配 negative 的文档仍会返回,但评分降低完全排除
适用场景需要展示但降权低质量内容需要完全排除某些内容
评分影响可控的降权(通过 negative_boost完全不影响评分(只是过滤)

5.2.6 典型应用场景

  • 降权低质量内容:如示例中的山寨品牌。
  • 处理过时内容:降权旧文章但不完全排除。
  • 广告混合排序:对广告内容适当降权。
  • 用户偏好处理:对用户不喜欢的类型降权。

5.2.7 参数注意事项

  • negative_boost 必须是 0 0 0 1 1 1 之间的浮点数:

    • 0.2 0.2 0.2 表示降权到原评分的 20 % 20\% 20%
    • 1.0 1.0 1.0 相当于没有效果。
    • 0.0 0.0 0.0 相当于完全排除(此时应使用 bool + must_not)。
  • 可以组合多个 positivenegative 条件:

    "positive": {"bool": {"should": [{ "match": { "title": "手机" } },{ "match": { "description": "智能" } }]}
    },
    "negative": {"bool": {"should": [{ "term": { "brand": "山寨" } },{ "range": { "price": { "lt": 100 } } }]}
    }
    

5.2.8 性能考虑

  • 比纯过滤(bool + must_not)消耗更多资源,因为要计算被降权文档的评分。
  • 对于需要完全排除的大量文档,建议使用 bool + must_not 过滤。
  • 适合处理少量需要降权而非完全排除的文档。

5.3 使用 Script Score

{"query": {"script_score": {"query": { "match": { "title": "手机" } },"script": {"source": "_score * doc['popularity'].value * params.weight","params": { "weight": 1.5 }}}}
}
  • 首先执行基础 match 查询,找出所有标题包含 “手机” 的文档,并计算原始 _score
  • 对每个匹配的文档:
    • 获取其 popularity 字段的值。
    • 使用脚本计算新评分:新评分 = _score × popularity × 1.5
  • 按照计算出的新评分对文档进行排序。
  • 返回结果。

6.相关度评分控制技巧

  • 理解评分因素
    • 词频(Term Frequency
    • 逆文档频率(Inverse Document Frequency
    • 字段长度归一值(Field-length norm
  • 使用 Explain API 分析评分
    GET /products/_search
    {"explain": true,"query": { "match": { "title": "手机" } }
    }
    
  • 调整相似度算法
    • 可配置 BM25 参数(k1b)。
    • 或完全自定义相似度实现。
  • 查询结构调整
    • 合理使用 bool 查询的 should / must / filter
    • 调整不同子句的 boost 值。

自定义评分是 Elasticsearch 强大的功能之一,合理使用可以显著提升搜索体验,但也需要谨慎设计以避免性能问题和不可预期的排序结果。

http://www.dtcms.com/a/268149.html

相关文章:

  • 评论区实现 前端Vue
  • 【openp2p】 学习4: 纳秒级别的时间同步算法及demo
  • 数学建模的一般步骤
  • FastAPI+React19开发ERP系统实战第04期
  • Hadoop YARN 命令行工具完全指南
  • ProCCD复古相机:捕捉复古瞬间
  • uniapp的光标跟随和打字机效果
  • LangChain有中文网可以访问,还有教程可以学
  • 手机FunASR识别SIM卡通话占用内存和运行性能分析
  • Jailer:一款免费的数据库子集化和数据浏览工具
  • ragflow本地部署教程linux Ubuntu系统
  • Android studio在点击运行按钮时执行过程中输出的compileDebugKotlin 这个任务是由gradle执行的吗
  • 《前端路由重构:解锁多语言交互的底层逻辑》
  • 【Linux笔记】Linux的常见命令(部署Java程序)
  • 基于大数据的高效并行推荐系统
  • VSCode+arm-none-eabi-gcc交叉编译+CMake构建+OpenOCD(基于Raspberry Pico RP2040)
  • C 语言指针与作用域详解
  • 百度文心大模型 4.5 开源深度测评:技术架构、部署实战与生态协同全解析
  • Gitee DevOps:全流程自动化的效率革命
  • DeepSORT算法流程详解
  • 基于Flask+Jinja2的快捷教务系统(后端链接到新版正方教务系统)
  • k8s-服务发布基础
  • 数据结构实验习题
  • 定时器和守护线程
  • 【Guava】1.0.设计虚拟机的方向
  • tensorflow武林志第二卷第九章:玄功九转
  • 广东省省考备考(第四十天7.6)——资料分析(第八节课)
  • Python Bcrypt详解:从原理到实战的安全密码存储方案
  • 【C++】C++四种类型转换操作符详解
  • 【Note】《Kafka: The Definitive Guide》第一章:Meet Kafka