首页 > 其他分享 >ES自定义评分机制:function_score查询详解

ES自定义评分机制:function_score查询详解

时间:2022-12-07 20:08:59浏览次数:64  
标签:function 得分 num 自定义 查询 access score 文档


一、function_score介绍

主要用于让用户自定义查询相关性得分,实现精细化控制评分的目的。

在ES的常规查询中,只有参与了匹配查询的字段才会参与记录的相关性得分score的计算。但很多时候我们希望能根据搜索记录的热度、浏览量、评分高低等来计算相关性得分,提高用户体验。

官网介绍:​​function_score​

哪些信息是用户真正关心的?
搜索引擎本质是一个匹配过程,即从海量数据中找到匹配用户需求的内容。

ES自定义评分机制:function_score查询详解_自定义评分

除了根据用户输入的查询关键字去检索外,还应根据用户的使用习惯、浏览记录、最近关注、搜索记录的热度等进行更加智能化的匹配。

常见的一些场景:
1、在百度、谷歌中搜索内容;
2、在淘宝、京东上面搜索商品;
3、在抖音上搜索用户和短视频。

二、实战演示

1、创建索引

说明:创建博客blog索引,只有2个字段,博客名title和访问量access_num。
用户根据博客名称搜索的时候,既希望名称能尽可能匹配,也希望访问量越多的排在最前面,因为一般访问量越多的博客质量会越好,这样可以提高用户的检索体验。

DELETE /blog

PUT /blog
{
"mappings": {
"properties": {
"title": {
"type": "text",
"analyzer": "ik_max_word",
"search_analyzer": "ik_smart"
},
"access_num": {
"type": "integer"
}
}
}
}

2、添加测试数据

PUT blog/_doc/2
{
"title": "java入门到精通",
"access_num":30
}

PUT blog/_doc/3
{
"title": "es入门到精通",
"access_num":50
}

PUT blog/_doc/4
{
"title": "mysql入门到精通",
"access_num":30
}

PUT blog/_doc/5
{
"title": "精通spark",
"access_num":40
}

3、常规检索

直接使用match查询,只会根据检索关键字和title字段值的相关性检索排序。

GET /blog/_search
{
"query": {
"match": {
"title": "java入门"
}
}
}

查询结果L

"hits" : [
{
"_index" : "blog",
"_type" : "_doc",
"_id" : "1",
"_score" : 1.3739232,
"_source" : {
"title" : "java入门",
"access_num" : 20
}
},
{
"_index" : "blog",
"_type" : "_doc",
"_id" : "2",
"_score" : 1.0552295,
"_source" : {
"title" : "java入门到精通",
"access_num" : 30
}
},
……
]

4、采用function_score自定义评分

除了match匹配查询计算相关性得分,还引入了根据浏览量access_num计算得分。

GET /blog/_search
{
"query": {
"function_score": {
"query": {
"match": {
"title": "java入门"
}
},
"functions": [
{
"script_score": {
"script": {
"params": {
"access_num_ratio": 2.5
},
"lang": "painless",
"source": "doc['access_num'].value * params.access_num_ratio "
}
}
}
]
}
}
}

查询结果:
说明:尽管博客名为java入门的名称和搜索词更加匹配,但由于博客名为java入门到精通的博客访问量更高,最终检索品分更高,排名更靠前。

"hits" : [
{
"_index" : "blog",
"_type" : "_doc",
"_id" : "2",
"_score" : 79.14222,
"_source" : {
"title" : "java入门到精通",
"access_num" : 30
}
},
{
"_index" : "blog",
"_type" : "_doc",
"_id" : "1",
"_score" : 68.69616,
"_source" : {
"title" : "java入门",
"access_num" : 20
}
},

三、自定义评分类型

function_score 查询提供了多种类型的评分函数。

  • ​script_score​​ script脚本评分
  • ​weight​​ 字段权重评分
  • ​random_score​​ 随机评分
  • ​field_value_factor​​ 字段值因子评分
  • ​decay functions: gauss, linear, exp​​ 衰减函数

说明:
decay functions衰减函数太过复杂,这里暂时不作介绍。

1、script脚本评分

script_score 函数允许您包装另一个查询并选择性地使用脚本表达式从文档中的其他数字字段值派生的计算自定义它的评分。 这是一个简单的示例:

GET /_search
{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"script_score" : {
"script" : {
"source": "Math.log(2 + doc['likes'].value)"
}
}
}
}
}

请注意,与 custom_score 查询不同,查询的分数乘以脚本评分的结果。 如果你想禁止这个,设置 “boost_mode”: “replace”

2、weight 权重评分

weight函数是最简单的分支,它将得分乘以一个常数。请注意,普通的boost字段按照标准化来增加分数。
而weight函数却真真切切地将得分乘以确定的数值。

下面的例子意味着,在description字段中匹配了hadoop词条查询的文档,他们的分数将被乘以1.5.

GET /_search
{
"query": {
"function_score": {
"query": {
"match": { "message": "elasticsearch" }
},
"functions":[
{
"weight":1.5 ,
"filter": { "term": { "description": "hadoop" }}
},
{
"weight":3 ,
"filter": { "term": { "description": "flink" }}
}
]
}
}
}

3、random_score随机评分

random_score 生成从 0 到但不包括 1 的均匀分布的分数。默认情况下,它使用内部 Lucene doc id 作为随机源。

如果您希望分数可重现,可以提供种子和字段。 然后将基于此种子、所考虑文档的字段最小值以及基于索引名称和分片 id 计算的盐计算最终分数,以便具有相同值但存储在不同索引中的文档得到 不同的分数。

请注意,位于同一个分片内且具有相同字段值的文档将获得相同的分数,因此通常希望使用对所有文档具有唯一值的字段。 一个好的默认选择可能是使用 _seq_no 字段,其唯一的缺点是如果文档更新,分数会改变,因为更新操作也会更新 _seq_no 字段的值。

GET /_search
{
"query": {
"function_score": {
"random_score": {
"seed": 10,
"field": "_seq_no"
}
}
}
}

4、field_value_factor 字段值因子评分

field_value_factor 函数允许您使用文档中的字段来影响分数。 它类似于使用 script_score 函数,但是,它避免了脚本的开销。 如果用于多值字段,则在计算中仅使用该字段的第一个值。

举个例子,假设你有一个用数字 likes 字段索引的文档,并希望用这个字段影响文档的分数,一个这样做的例子看起来像:

GET /_search
{
"query": {
"function_score": {
"field_value_factor": {
"field": "likes",
"factor": 1.2,
"modifier": "sqrt",
"missing": 1
}
}
}
}

得分计算公式: ​​sqrt(1.2 * doc['likes'].value)​

参数说明:

  • field

要从文档中提取的字段。

  • factor

与字段值相乘的可选因子,默认为 1。

  • modifier

应用于字段值的计算修饰符, none, log, log1p, log2p, ln, ln1p, ln2p, square, sqrt, or reciprocal,默认 none.

  • missing

如果文档没有该字段,则使用的值。 修饰符和因子仍然适用于它,就好像它是从文档中读取的一样。

5、Decay functions 衰减函数

衰减函数使用一个函数对文档进行评分,该函数根据文档的数字字段值与用户给定原点的距离而衰减。 这类似于范围查询,但具有平滑的边缘而不是框。

要对具有数字字段的查询使用距离评分,用户必须为每个字段定义原点和比例。 需要原点来定义计算距离的“中心点”,以及定义衰减率的比例尺。

好吧,一脸懵逼,这里就不继续介绍了。

放一个示例,大家有兴趣可以参考官方文档继续研究下。

GET /_search
{
"query": {
"function_score": {
"functions": [
{
"gauss": {
"price": {
"origin": "0",
"scale": "20"
}
}
},
{
"gauss": {
"location": {
"origin": "11, 12",
"scale": "2km"
}
}
}
],
"query": {
"match": {
"properties": "balcony"
}
},
"score_mode": "multiply"
}
}
}

四、合并得分

GET /_search
{
"query": {
"function_score": {
"query": { "match_all": {} },
"boost": "5",
"functions": [
{
"filter": { "match": { "test": "bar" } },
"random_score": {},
"weight": 23
},
{
"filter": { "match": { "test": "cat" } },
"weight": 42
}
],
"max_boost": 42,
"score_mode": "max",
"boost_mode": "multiply",
"min_score" : 42
}
}
}

参数说明:

  • max_boost
    可以通过设置 max_boost 参数将新分数限制为不超过某个限制。 max_boost 的默认值是 FLT_MAX。
  • min_score
    默认情况下,修改分数不会更改匹配的文档。 要排除不满足某个分数阈值的文档,可以将 min_score 参数设置为所需的分数阈值。

参数 score_mode 指定如何组合计算的分数:

  • ​multiply​​ 相乘 (default)
  • ​sum​​ 求和
  • ​avg​​ 平均分
  • ​first​​ 使用具有匹配过滤器的第一个函数的得分
  • ​max​​ 使用最高分
  • ​min​​ 使用最低分

boost_mode定义新计算的分数与查询的分数相结合。 具体选项:

  • ​multiply​​ 查询得分和函数得分相乘,默认
  • ​replace​​ 仅使用函数得分,查询得分被忽略
  • ​sum​​ 查询得分和函数得分求和
  • ​avg​​ 查询得分和函数得分取平均值
  • ​max​​ 取查询得分和函数得分的最大值
  • ​min​​ 取查询得分和函数得分的最小值

总结

本文主要介绍了ES中自定义评分函数function_score的使用场景以及各种评分函数的用法。


标签:function,得分,num,自定义,查询,access,score,文档
From: https://blog.51cto.com/u_15905482/5919981

相关文章

  • Function函数 Array函数
    Function:函数(方法)对象1.创建∶1.varfun=newFunction(形式参数列表,方法体);/忘掉吧2.function方法名称(形式参数列表){方法体}I3.var方法名=function(形式参数列......
  • 开源web自定义表单有哪几个特点?
    目前,市场正在蓬勃发展中,作为企业,采用传统表单的弊端也逐渐显现出来,面临比较大的问题就是办公效率得不到提升。在各行各业正积极筹备朝着数字化方向转型的背景下,采用开源web......
  • 自定义指令(全局和局部作用)
    自定义指令分为两个字情景1.在某一个vue文件里,而不是全局2.在main.ts文件里注册全局的自定义指令vue文件<scriptsetup>import{ref,onMounted}from'vue'letn=ref(......
  • PHP 自定义 数组根据键去重
    去重前$result=$this->unique_array_by_key($result,"id");functionunique_array_by_key($array,$unique_key){$tmp_key[]=array();forea......
  • Oracle迁移Mysql的sql语句修改需创建的function代码
    DELIMITER $$CREATE  FUNCTION `to_date`(in_str varchar(50), in_format varchar(50)) RETURNS datetime    DETERMINISTICBEGIN DECLARE my_format ......
  • vue i18n _ctx.$t is not a function
     一、问题Uncaught(inpromise)TypeError:_ctx.$tisnotafunctionatSelect.vue:51:95atrenderFnWithContext(runtime-core.esm-bundler.js:852:21)......
  • leaflet 用自定义pane实现图层顺序调整
    在Leaflet中,mappanes隐式地将图层组合在一起,而开发者并不知道这一点。这种分组允许Web浏览器以比单独处理图层更有效的方式同时处理多个图层。Mappanes使用z-ind......
  • <三>function函数对象类型的应用示例
    std::function是一组函数对象包装类的模板,实现了一个泛型的回调机制。function与函数指针比较相似,优点在于它允许用户在目标的实现上拥有更大的弹性,即目标既可以是普通函数......
  • 对于噪声数据理解以及Min-Max 规范化和 Score规范化(零-均值规范化)的实例【数据预处
    一.噪声数据噪声数据(NoisyData)就是无意义的数据,这个词通常作为损坏数据的同义词使用。1.分箱:通过考察数据的“近邻”(周围的值)来光滑有序数据的值。局部光滑2.回归:......
  • Vue3必会技巧-自定义Hooks
    Vue3自定义Hooks定义:个人理解:一些可复用的方法像钩子一样挂着,可以随时被引入和调用以实现高内聚低耦合的目标,应该都能算是hook;为什么Vue3要用自定义Hook?:结论:就是为了......