一、function_score介绍

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

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

官网介绍:function_score

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

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

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

二、实战演示

1、创建索引

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

DELETE /blogPUT /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的使用场景以及各种评分函数的用法。

ES自定义评分机制:function_score查询详解相关推荐

  1. Elasticsearch实战——function_score 查询详解

    Elasticsearch实战--function_score 查询详解 文章目录 Elasticsearch实战--function_score 查询详解 1. function_score简介 2 ...

  2. java中定义score方法_elasticsearch 自定义 script score JavaAPI查询详解

    一:自定义score的应用场景 先打个比方,比如新产品上架了,我想让最新上架的产品搜索时候,排在前面,怎么办呢?很简单按时间排序.嗯这种方法很好实现. 但下面又有个需求,比如我要求排序中上架时间的比重 ...

  3. ElasticSearch 全文搜索引擎的查询详解①(Ubuntu版 v6.6.2)

    ElasticSearch 全文搜索引擎的查询详解①(Ubuntu版 v6.6.2) 1. 前提 2. 轻量搜索 2.1 单条件查询 2.2 多条件查询 2.3 不指定属性查询(查询所有文档属性)-- ...

  4. 在python中使用关键字define定义函数_python自定义函数def的应用详解

    这里是三岁,来和大家唠唠自定义函数,这一个神奇的东西,带大家白话玩转自定义函数 自定义函数,编程里面的精髓! def 自定义函数的必要函数:def 使用方法:def 函数名(参数1,参数2,参数-): ...

  5. Android-Binder进程间通讯机制-多图详解

    本系列: Android-Binder进程间通讯机制-多图详解 一次Binder通信最大可以传输多大的数据?​​​​​​​ 关于Binder (AIDL)的 oneway 机制 概述 最近在学习Bin ...

  6. python def函数报错详解_python自定义函数def的应用详解

    这篇文章主要介绍了python自定义函数def的应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 这里是三岁,来和大家唠唠 ...

  7. jdbc mysql 自动重连_JDBC实现Mysql自动重连机制的方法详解

    JDBC是Java程序连接和访问各种数据库的API,它可以提供Java程序和各种数据库之间的连接服务,下面是爱站技术频道小编为大家带来的JDBC实现Mysql自动重连机制的方法详解. 日志:using ...

  8. 03 mysql数据查询_MySql学习day03:数据表之间的连接、查询详解

    主键: 关键字:primary key 特点:不能为null,并且唯一. 主键分类: 逻辑主键:例如ID,不代表实际的业务意义,只是用来唯一标识一条记录(推荐) 业务主键:例如username,参与实 ...

  9. mysql多表查询详解_MySQL多表查询详解上

    时光在不经意间,总是过得出奇的快.小暑已过,进入中暑,太阳更加热烈的绽放着ta的光芒,...在外面被太阳照顾的人们啊,你们都是勤劳与可爱的人啊.在房子里已各种姿势看我这篇这章的你,既然点了进来,那就由 ...

最新文章

  1. 关于《强化狼群等级制度的灰狼优化算法》的问题邮件回复
  2. Jvm 系列(二):Jvm 内存结构
  3. 快点啊,大工程禁用Visual Assist,禁用符号加载
  4. 传统产业已死,新的产业在何方?
  5. javascript终极屏蔽右键/禁止复制/禁止另存/禁止右键/禁止选取/禁止粘贴的方法...
  6. Linux系统检测工具 三(Free,Top,ps,Vmstat,Sysstat)
  7. 关系代数的自然连接符号_初中数学知识清单之代数式的认识
  8. 您可能不知道的 C++ 关键字
  9. 动态规划 —— 背包问题 P03 —— 多重背包
  10. [转载]未在本地计算机上注册“microsoft.ACE.oledb.12.0”提供程序。
  11. 去掉jsp页面自动生成的空行
  12. 关于计算流体力学,你知道多少?
  13. 【Linux 内核网络协议栈源码剖析】sendto 函数剖析
  14. python制作圆形按钮_圆形按钮tkinter python
  15. N个球放M个盒子问题
  16. (一)关于爬虫之请求
  17. [Python]_[初级]_[使用PyCharm时不识别根包位置和Debug时报ModuleNotFoundError错误]
  18. 欧姆龙CP系列PLC以太网通讯连接SCADA介绍
  19. 数据残酷物语:北上广深租房图鉴
  20. 实现TextView尾部追加可点击的Icon和文本

热门文章

  1. 福建最新初级消防设施操作员考试真题及答案
  2. 用网线给服务器装系统,只用网线从零开始安装系统
  3. WPS 从今以后我再也不会用了 记录一下!
  4. 植物神经紊乱,适量进食米饭有什么好处?
  5. 考心理健康教育教师资格证-初出茅庐
  6. 使用C加加实现计算器功能。可以实现加减乘除。需要用到内联。函数重载。new运算符。缺省参数
  7. Apollo星火计划学习笔记|L1 Apollo平台安装(2021年9月更新)
  8. python找零_python 找零问题 动态规划
  9. heic格式图片转为jpg格式 安装pyheif
  10. 【python】生成随机n位数字与字母组合(创建随机)