深度探索 Elasticsearch 8.X:function_score 参数解读与实战案例分析

在 Elasticsearch 中,function_score 可以让我们在查询的同时对搜索结果进行自定义评分。

function_score 提供了一系列的参数和函数让我们可以根据需求灵活地进行设置。

近期有同学反馈,function_score 的相关参数不好理解,本文将深入探讨 function_score 的核心参数和函数。

d723694e7858d4f6a2b5eb4f4f29b80c.png

1、function_score 函数的用途及适用场景

Elasticsearch 的 function_score 查询是一种强大的工具,它可以允许我们修改文档的基本的相关评分,让我们在特定的应用场景下获得更好的搜索结果。

这个功能通过提供了一组内置函数(如 script_score, weight, random_score, field_value_factor, decay functions等),以及一系列参数(如boost_mode和score_mode等)来实现。

以下是一些 function_score 可以应用的场景:

1.1 用户偏好场景

如果需要了解用户的兴趣或者行为,我们可以使用 function_score 来提升用户可能感兴趣的结果。

比如在推荐系统中,如果我们已知道用户喜欢某个作者的文章,可以提升这个作者的文章的得分。

比如最近火热的“罗刹海市”就被网易云音乐推荐到最前面。

9aecf7b958fbb6594ac6dee444385828.png

1.2 随机抽样场景

如果我们需要从一个大的数据集中随机抽样,可以使用 random_score 函数。

这个函数会给每个文档生成一个随机得分,从而让我们能够得到随机的搜索结果。

1.3 时间敏感的查询场景

对于一些时间敏感的数据,比如新闻、博客文章或者论坛帖子,新的文档通常比旧的文档更相关。

在这种情况下,我们可以使用 decay functions(衰减函数) 来降低旧的文档的得分。

1.4 地理位置敏感的查询场景

如果我们的应用关心地理位置,比如房地产或者旅游相关的应用。

可以使用 decay functions (衰减函数)来提升接近某个地理位置的文档的得分。

1.5 特定字段影响场景

如果我们的文档有一些字段值可以影响相关度评分,可以使用 field_value_factor (字段值因子)函数。

比如在电商场景,一个商品的销量、评分或者评论数量可能会影响搜索结果的排序。

总的来说,function_score 提供了一种灵活的方式来满足各种复杂的相关度评分需求。

2、function_score 参数介绍

2.1 boost_mode 参数

boost_mode 决定了如何将查询得分和函数得分进行组合。

可接受的参数有:

boost_mode描述
multiply查询得分和函数得分相乘(默认值)
sum查询得分和函数得分相加
avg查询得分和函数得分的平均值
first仅仅使用函数得分
max查询得分和函数得分中的最大值
min查询得分和函数得分中的最小值
replace完全替换查询得分,只使用函数得分

2.2 score_mode

score_mode 决定了如何处理多个函数的分数。

可接受的参数有:

score_mode描述
multiply各个函数得分相乘
sum各个函数得分相加(默认值)
avg各个函数得分的平均值
first仅仅使用第一个函数的得分
max各个函数得分中的最大值
min各个函数得分中的最小值

2.3 提供的函数

function_score 提供了多种函数类型来进行自定义评分:

Score Function描述
script_score用脚本计算得分
weight简单地修改查询得分,不考虑字段值
random_score生成随机得分
field_value_factor使用字段值进行计算得分
decay functions衰减函数,根据字段值的距离计算得分,越近得分越高

3、function_score 使用实战解读

3.1 构造数据

为了帮助大家更好地理解,我们将创建一个简单的索引,插入一些文档,并对它们执行 function_score 查询。

假设我们有一个名为 articles 的索引,里面存储了一些博客文章的数据,包括作者(author),标题(title),内容(content),以及这篇文章的喜欢数量(likes)。

首先,创建索引并添加一些文档:

PUT /articles
{"mappings": {"properties": {"title": { "type": "text" },"author": { "type": "text" },"content": { "type": "text" },"likes": { "type": "integer" }}}
}POST /_bulk
{ "index" : { "_index" : "articles", "_id" : "1" } }
{ "title": "Elasticsearch Basics", "author": "John Doe", "content": "This article introduces the basics of Elasticsearch.", "likes": 100 }
{ "index" : { "_index" : "articles", "_id" : "2" } }
{ "title": "Advanced Elasticsearch", "author": "Jane Doe", "content": "This article covers advanced topics in Elasticsearch.", "likes": 500 }
{ "index" : { "_index" : "articles", "_id" : "3" } }
{ "title": "Elasticsearch Function Score Query", "author": "John Doe", "content": "This article discusses the function_score query in Elasticsearch.", "likes": 250 }

现在我们有了一些文档,让我们对它们执行 function_score 查询。

3.2 使用 script_score 函数实现基于 'likes' 字段的对数加权排序

GET /articles/_search
{"query": {"function_score": {"query": {"match_all": {}},"boost": "5","functions": [{"script_score": {"script": {"source": "Math.log(1 + doc['likes'].value)"}}}],"boost_mode": "multiply"}}
}

上述查询使用了 Elasticsearch 的 function_score 查询。

它首先对 "articles" 索引中的所有文档进行匹配(使用 match_all 查询),然后使用一个脚本函数(script_score),该脚本会计算每个文档的 "likes" 字段的自然对数值加一(Math.log(1 + doc['likes'].value)),然后把这个得分与原始查询得分相乘(由于 boost_mode 被设为了 "multiply"),最终的得分再乘以5(由于 boost 被设为了 "5")。这种查询用于根据 "likes" 字段对结果进行加权排序。

执行结果如下:

22b92e539f7aa22f553a41ed34b52fd0.png

3.3 使用 random_score 生成基于 'likes' 字段的全随机结果查询

GET /articles/_search
{"query": {"function_score": {"query": { "match_all": {} },"functions": [{"random_score": {"field": "likes"}}],"boost_mode": "replace"}}
}

上述查询使用 Elasticsearch 的 function_score 查询,并配合使用 random_score 函数。random_score 函数根据 "likes" 字段的值生成一个随机分数。

重要的是,由于没有提供一个固定的种子(seed),所以每次执行这个查询都会返回一个全新的随机排序结果。

match_all 是基础查询,用来匹配所有文档。然后 random_score 函数基于 "likes" 字段值生成随机分数。

boost_mode 设为 "replace" 表示忽略基础查询的分数,完全使用 random_score 函数的分数作为最终结果。所以,这个查询会在每次执行时都返回全新的随机排序结果。

执行结果如下图所示:

3b4b43b989c1d748efde48c9b6f526c6.png

3.4 field_value_factor 函数根据某个字段的值来修改_score

这对于一些字段很有用,比如"likes":一篇有很多"likes"的文章可能比"likes"少的文章更相关。

示例如下:

GET /articles/_search
{"query": {"function_score": {"query": {"match": {"content": "Elasticsearch"}},"functions": [{"field_value_factor": {"field": "likes","factor": 1.2,"modifier": "sqrt","missing": 1}}],"boost_mode": "multiply"}}
}

在这个查询中:

  • "match": { "content": "Elasticsearch" }

表示基础查询是在 "content" 字段中匹配包含 "Elasticsearch" 的文章。

  • field_value_factor

函数用来基于 "likes" 字段的值调整查询得分。它首先取 "likes" 字段的值,如果文档没有 "likes" 字段或者该字段的值为空,那么将使用 "missing" 参数指定的默认值1。然后,它将取得的值乘以 "factor" 参数指定的因子1.2。最后,它将结果进行 "modifier" 参数指定的平方根运算("sqrt")。

  • boost_mode

参数设置为 "multiply",这表示将基础查询的得分和 field_value_factor 函数计算得出的得分相乘,以得到最终的文档得分。

所以,这个查询会返回包含 "Elasticsearch" 的文章,并且文章的得分会根据 "likes" 字段的值进行调整,"likes" 值越高的文章,得分也会越高。

执行结果如下:

1d7fbf61188ca18f6cca091c605d5dc9.png

3.5 decay functions 根据某个字段的值的距离来调整_score。

如果值接近某个中心点,得分就会更高。这对于日期或地理位置字段特别有用。

Elasticsearch 提供了三种衰减函数:线性(linear)、指数(exp)、和高斯(gauss)。

以下是使用 gauss 函数的一个示例:

GET /articles/_search
{"query": {"function_score": {"query": {"match": {"content": "Elasticsearch"}},"functions": [{"gauss": {"likes": {"origin": "100","scale": "20","offset": "0","decay": 0.5}}}],"boost_mode": "multiply"}}
}

上述执行可概括为:使用 function_score 和 gauss 函数对含有 'Elasticsearch' 的文章进行基于 'likes' 字段的高斯衰减得分调整"。

在这个查询中:

  • "match": { "content": "Elasticsearch" }

表示基础查询是在 "content" 字段中匹配包含 "Elasticsearch" 的文章。

  • gauss

函数则是用来对 "likes" 字段的值进行高斯衰减处理。

其中,

参数描述
origin100期望的中心点,即 "likes" 字段的最理想值
scale20表示衰减的速度,也就是距离 "origin" 值多远时,得分会衰减到原始得分的一半
offset0表示在距离 "origin" 多少的范围内不进行衰减
decay0.5表示当距离超过了 "scale" 之后,得分会以多快的速度衰减,例如 0.5 表示超过 "scale" 距离后,得分会衰减到原始得分的一半
  • boost_mode

参数设置为 "multiply",这表示将基础查询的得分和 gauss 函数计算得出的得分相乘,以得到最终的文档得分。

所以,这个查询会返回包含 "Elasticsearch" 的文章,并且文章的得分会根据 "likes" 字段的值进行高斯衰减处理,"likes" 值越接近100的文章,得分也会越高。

12a3daea1d5292f630f6aba0ac680194.png

4、小结

在深入了解 Elasticsearch 的 function_score 后,我们可以明显感受到其在搜索应用中的强大作用。无论是基于特定字段值的排序,还是利用自定义脚本微调搜索结果,function_score 都能发挥其出色的性能。

尽管 function_score 的参数和选项多样,初看可能会觉得复杂,但只需理解各参数的含义和作用,我们就能根据需求灵活运用。实际案例中,我们使用了 script_score、field_value_factor、random_score 和 decay functions 等函数,演示了如何通过 function_score 满足复杂的搜索需求。

但是,我们也必须注意,在使用 function_score 时,要慎重考虑性能问题,因为复杂的函数和脚本可能占用大量计算资源。在实际应用中,我们应始终关注这一点,以维护良好的系统性能。

此外,随着数据和用户行为的不断变化,我们需要持续观察、学习和调整搜索策略,以不断提升用户体验。在这个过程中,function_score 将是我们强有力的工具。

总的来说,Elasticsearch 的 function_score 是一个强大而灵活的工具,只要我们深入了解并恰当使用,就能够挖掘其巨大的潜力,提升我们的搜索应用性能和用户体验。

推荐阅读

  1. 全网首发!从 0 到 1 Elasticsearch 8.X 通关视频

  2. 重磅 | 死磕 Elasticsearch 8.X 方法论认知清单

  3. 如何系统的学习 Elasticsearch ?

  4. 2023,做点事

  5. 实战 | Elasticsearch自定义评分的N种方法

  6. 干货 | 一步步拆解 Elasticsearch BM25 模型评分细节

  7. Elasticsearch 如何把评分限定在0到1之间?

9b5b2a0147ff9bcca5dce3538627f52d.jpeg

更短时间更快习得更多干货!

和全球 近2000+ Elastic 爱好者一起精进!

80c49c1c129db7afd4c2a2c3a2338ef2.gif

大模型时代,抢先一步学习进阶干货!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/13475.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据动态填充到element表格;将带有标签的数据展示为文本格式】

一&#xff1a;数据动态填充到element表格&#xff1b; 二&#xff1a;将带有标签的数据展示为文本格式&#xff1b; 1、 <el-row><el-col :span"24"><el-tabs type"border-card"><el-tab-pane label"返回值"><el-…

基于OpenCV solvePnP函数估计头部姿势

人脸识别 文章目录 人脸识别一、姿势估计概述1、概述2、姿态估计3、在数学上表示相机运动4、姿势估计需要什么5、姿势估计算法6、Levenberg-Marquardt 优化 二、solvePnP函数1、函数原型2、参数详解 三、OpenCV源码1、源码路径 四、效果图像示例参考链接 一、姿势估计概述 1、…

Go语言学习笔记(狂神说)

Go语言学习笔记&#xff08;狂神说&#xff09; 视频地址&#xff1a;https://www.bilibili.com/video/BV1ae41157o9 1、聊聊Go语言的历史 聊聊Go语言的历史-KuangStudy-文章 2、Go语言能做什么 下面列举的是原生使用Go语言进行开发的部分项目。 Docker Docker 是一种操作…

【机器学习】西瓜书学习心得及课后习题参考答案—第4章决策树

这一章学起来较为简单&#xff0c;也比较好理解。 4.1基本流程——介绍了决策树的一个基本的流程。叶结点对应于决策结果&#xff0c;其他每个结点则对应于一个属性测试&#xff1b;每个结点包含的样本集合根据属性测试的结果被划分到子结点中&#xff1b;根结点包含样本全集&a…

Flutter 调试工具篇 | 壹 - 使用 Flutter Inspector 分析界面

theme: cyanosis 1. 前言 很多朋友可能在布局过程中、或者组件使用过程中&#xff0c;会遇到诸如颜色、尺寸、约束、定位等问题&#xff0c;可能会让你抓耳挠腮。俗话说&#xff0c;磨刀不误砍柴工&#xff0c;会使用工具是非常重要的&#xff0c;其实 Flutter 提供了强大的调试…

10分钟实现任务调度平台搭建

日常项目中&#xff0c;会有很多需要定时执行的任务&#xff0c;而这些任务的变化比较多&#xff0c;可能随时都要调整&#xff0c;那么对调度的灵活性要求比较高。我们传统的Spring Task或者Quartz&#xff0c;可以实现定时任务调度&#xff0c;但是内置在代码里&#xff0c;修…

JA64 1+2+3+...n

一、题目 求123...n_牛客题霸_牛客网 二、代码 1.使用静态成员变量构造函数 class SUM {private:static int _i;static int _ret;public:SUM(){_ret _ret _i;_i;}static int GetRet(){return _ret;} }; int SUM::_i1; int SUM::_ret0;class Solution { public:int Sum_So…

【java的类型数据】——八大类型数据

文章目录 前言字面常量字面常量的分类: 数据类型和变量变量的包装类和范围范围整型变量byteintshortlong 浮点型变量双精度浮点型double单精度浮点型float 字符型变量char布尔型变量 boolean 类型转换自动类型转换&#xff08;隐式&#xff09;强制类型转换&#xff08;显式&am…

一个字符驱动示例 -- 微秒级别周期 反转GPIO

仅作为自我记录的一个demo 本次GPIO以微妙级别频率的反转实验有以下几个启示&#xff1a; 一开始在应用层做延时&#xff0c;来实现2微妙周期&#xff0c;占空比50%的GPIO反转&#xff0c;发现波形的频率一直上不去&#xff0c;只能在25hz徘徊&#xff0c;后来索性去掉延时&am…

flink写入到kafka 大坑解析。

1.kafka能不能发送null消息&#xff1f; 能&#xff01; 2 flink能不能发送null消息到kafka&#xff1f; 不能&#xff01; public static void main(String[] args) throws Exception {StreamExecutionEnvironment env StreamExecutionEnvironment.getExecutionEnvironment(…

JavaWeb+jsp+Tomcat的叮当书城项目

点击以下链接获取源码&#xff1a; https://download.csdn.net/download/qq_64505944/88123111?spm1001.2014.3001.5503 技术&#xff1a;ssm jsp JDK1.8 MySQL5.7 Tomcat8.3 源码数据库课程设计 功能&#xff1a;管理员与普通用户和超级管理员三个角色&#xff0c;管理员可…

浅谈 Spring AOP 思想

Spring AOP AOP 切面编程普通代理类JDK动态代理Cglib动态代理AOPAOP术语AOP切面编程的优势Advice通知类型&#xff08;5种&#xff09;通知的执行顺序 Order切入点表达式表达式execution注解annotation Spring事务管理Transactional 及 Transactional 的两个属性Transactional …

常用直线模组的类型

目前&#xff0c;直线模组的应用非常广泛&#xff0c;而且直线模组的种类也有很多可以满足每个行业的应用要求&#xff0c;那么常见的直线模组类型有哪些&#xff0c;大家知道吗&#xff1f; 1、全封闭滚珠丝杆直线模组&#xff1a; 在半封闭式的基础上增加了不锈钢带防尘结构…

[Angular] Import TranslateModule in Angular 16

1.Background Angular 更新至V16版后&#xff0c;支援 standalone&#xff0c;故移除了 NgModule&#xff0c;而TranslateModule 又要在AppModule中 import&#xff0c;那该如何做呢&#xff1f; 2.NPM packages installation npm install ngx-translate/core npm install n…

BUUCTF——reverse3 适合新手的关于base64加密算法代码的分析

作为一个逆向小白&#xff0c;学了点加密算法就来BUU找点乐子&#xff0c;前7题蛮简单的&#xff0c;然后做到了reverse3&#xff0c;典型的base64加密算法&#xff0c;让我折腾了好久&#xff0c;写篇博客记录一下 顺便说下很多博客并没有对这里的加密算法进行代码上的分析&a…

分享VMware Workstation Pro ESXI7创建虚拟机和配置硬盘空间(分享自己的学习历程意在帮助有需要的小伙伴)

背景&#xff1a;因公司项目需求改用VMware Workstation Pro&#xff0c;已经使用1个月目前除了中途出现过一次问题被解决后一直稳定运行至今&#xff0c; 1:这里贴出拿出现的问题提示及解决方法的链接&#xff1a;解决vmWare ESXI 7.3报错; 2:如果你是第一次接触VMware Work…

Echarts 文字太长用省略号代替

xAxis: [{type: category,data: [materialUserEchartsDate.value[0] ? materialUserEchartsDate.value[0].name : ,materialUserEchartsDate.value[1] ? materialUserEchartsDate.value[1].name : ,materialUserEchartsDate.value[2] ? materialUserEchartsDate.value[2].na…

二、前端高德地图、渲染标记(Marker)引入自定义icon,手动设置zoom

要实现这个效果&#xff0c;我们先看一下目前的页面展示&#xff1a; 左边有一个图例&#xff0c;我们可以方法缩小地图&#xff0c;右边是动态的marker标记&#xff0c;到时候肯定时候是后端将对应的颜色标识、文字展示、坐标点给咱们返回、我们肯定可以拿到一个list&#xf…

【广州华锐互动】无人值守变电站AR虚拟测控平台

无人值守变电站AR虚拟测控平台是一种基于增强现实技术的电力设备巡检系统&#xff0c;它可以利用增强现实技术将虚拟信息叠加在真实场景中&#xff0c;帮助巡检人员更加高效地完成巡检任务。这种系统的出现&#xff0c;不仅提高了巡检效率和准确性&#xff0c;还降低了巡检成本…

企业级敏捷转型探索与实践︱极狐Gitlab战略运营部PMO郝韫

极狐Gitlab战略运营部PMO郝韫先生受邀为由PMO评论主办的2023第十二届中国PMO大会演讲嘉宾&#xff0c;演讲议题&#xff1a;企业级敏捷转型探索与实践。大会将于8月12-13日在北京举办&#xff0c;敬请关注&#xff01; 议题简要&#xff1a; 打造持续创新、快速成长的敏捷组织…