Es_算分函数使用详情

2023-11-14

算分函数查询

相关性计算

当我们利用match查询时,文档结果会根据与搜索词条的关联度打分(_score),返回结果时按照分值降序排列。

例如,我们搜索 “虹桥如家”,结果如下:

[
  {
    "_score" : 17.850193,
    "_source" : {
      "name" : "虹桥如家酒店真不错",
    }
  },
  {
    "_score" : 12.259849,
    "_source" : {
      "name" : "外滩如家酒店真不错",
    }
  },
  {
    "_score" : 11.91091,
    "_source" : {
      "name" : "迪士尼如家酒店真不错",
    }
  }
]

在elasticsearch中,早期使用的打分算法是TF-IDF算法,公式如下:

image-20210721190152134

在后来的5.1版本升级中,elasticsearch将算法改进为BM25算法,公式如下:

image-20210721190416214

TF-IDF算法有一个缺陷,就是词条频率越高,文档得分也会越高,单个词条对文档影响较大。而BM25则会让单个词条的算分有一个上限,曲线更加平滑:

image-20210721190907320

根据相关度打分是比较合理的需求,但合理的不一定是产品经理需要的。

以百度为例,你搜索的结果中,并不是相关度越高排名越靠前,而是谁掏的钱多排名就越靠前。如图:

image-20210721191144560

要想人为控制相关性算分,就需要利用elasticsearch中的function score 查询了。

算分函数语法

image-20210721191544750

function score 查询中包含四部分内容:

  • 原始查询条件:query部分,基于这个条件搜索文档,并且基于BM25算法给文档打分,原始算分(query score)
  • 过滤条件:filter部分,符合该条件的文档才会重新算分
  • 算分函数:符合filter条件的文档要根据这个函数做运算,得到的函数算分(function score),有四种函数
    • weight:函数结果是常量
    • field_value_factor:以文档中的某个字段值作为函数结果
    • random_score:以随机数作为函数结果
    • script_score:自定义算分函数算法
  • 运算模式:算分函数的结果、原始查询的相关性算分,两者之间的运算方式,包括:
    • multiply:相乘
    • replace:用function score替换query score
    • 其它,例如:sum、avg、max、min

function score的运行流程如下:

  1. 根据原始条件查询搜索文档,并且计算相关性算分,称为原始算分(query score)

  2. 根据过滤条件,过滤出符合过滤条件的文档,基于算分函数运算,得到函数算分(function score)

  3. 原始算分(query score)和函数算分(function score)基于运算模式做运算,得到最终结果,作为相关性算分。

因此,其中的关键点是:

  • 过滤条件:决定哪些文档的算分被修改
  • 算分函数:决定函数算分的算法
  • 运算模式:决定最终算分结果
算分函数示例

需求:给“如家”这个品牌的酒店排名靠前一些

翻译一下这个需求,转换为之前说的四个要点:

  • 原始条件:不确定,可以任意变化
  • 过滤条件:brand = “如家”
  • 算分函数:可以简单粗暴,直接给固定的算分结果,weight
  • 运算模式:比如求和

因此最终的DSL语句如下:

#不添加算法函数,原始检索。如家酒店的相关性得分并不高
GET /hotel/_search
{
  "query": {
    "match": {
      "all": "北京酒店"
    }
  }
}

#使用算法函数,所有品牌为“如家”的酒店,在原始相关性得分基础上+10,最终相关性得分高了很多
GET /hotel/_search
{
  "query": {
    "function_score": {
      "query": {
        "match": {
          "all": "北京酒店"
        }
      },
      "functions": [
        {
          "filter": {"term": {"brand": "如家"}},
          "weight": 10
        }
      ],
      "boost_mode": "sum"
    }
  }
}

不添加算法函数,原始检索。如家酒店的相关性得分并不高

image-20220627173331283

使用算法函数,所有品牌为“如家”的酒店,在原始相关性得分基础上+10,最终相关性得分高了很多

image-20220627173436183

代码实例

image-20220629113515690

@Test
public void testFunctionScore() throws IOException {
    SearchRequest request = new SearchRequest("hotel");

    //设置查询条件
    FunctionScoreQueryBuilder scoreQueryBuilder = QueryBuilders.functionScoreQuery(
        //基础查询
        QueryBuilders.matchQuery("all", "北京酒店"),
        //对应DSL里functions数组
        new FunctionScoreQueryBuilder.FilterFunctionBuilder[]{
            new FunctionScoreQueryBuilder.FilterFunctionBuilder(
                //filter,过滤出来要重新算分的数据
                QueryBuilders.termQuery("brand", "希尔顿"),
                //设置算分函数,使用权重值
                ScoreFunctionBuilders.weightFactorFunction(10)
            )
        }
    );
    //处分函数的加权模式:Multiply,相乘。数据的原始得分 乘 权重值。如果不设置加权模式,默认就是相乘
    scoreQueryBuilder.boostMode(CombineFunction.MULTIPLY);

    request.source().query(scoreQueryBuilder);


    SearchResponse response = client.search(request, RequestOptions.DEFAULT);

    SearchHits result = response.getHits();
    //      获取总数量
    long total = result.getTotalHits().value;
    System.out.println("总数量:" + total);
    //      获取数据列表
    SearchHit[] hits = result.getHits();
    for (SearchHit hit : hits) {
        //获取文档对象的原始数据
        String docJson = hit.getSourceAsString();
        HotelDoc doc = JSON.parseObject(docJson, HotelDoc.class);
        System.out.println("查询得到的数据:" + doc);

        System.out.println("匹配度得分:" + hit.getScore());
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Es_算分函数使用详情 的相关文章

  • 将 pandas 数据框索引到 Elasticsearch 中,无需使用 elasticsearch-py

    我想将一堆大型 Pandas 数据帧 大约数百万行和 50 列 索引到 Elasticsearch 中 在寻找如何执行此操作的示例时 大多数人会使用elasticsearch py 的批量辅助方法 https elasticsearch p
  • 如何连接Kafka和Elasticsearch?

    我是Kafka的新手 我使用kafka通过logstash收集netflow 可以 并且我想将数据从kafka发送到elasticsearch 但是存在一些问题 我的问题是如何将 Kafka 与 Elasticsearch 连接起来 net
  • Elasticsearch 中的分析器有什么用?

    我在理解弹性搜索分析器时遇到一些问题 它的用途是什么以及如何使用它 From 本文 https www elastic co blog found text analysis part 1 有来自源文本的分词器和分词过滤器 我是否无法理解来
  • 如何用Python为ElasticSearch创建只读客户端?

    我想从 ES 读取数据 但不想意外向其中写入数据 无索引操作 这只是一种安全措施 以便以后修改查询函数的其他人不允许插入数据 当你说你想要只读客户端时 客户端强调您系统中的同一集群可能有其他客户端 然后阻止整个索引为只读将会阻止所有客户端的
  • Elasticsearch批量设置_id

    当我使用 id 设置将文档添加到 elasticsearch 时 我得到 Field id is a metadata field and cannot be added inside a document Use the index AP
  • Elasticsearch 崩溃后无法恢复

    磁盘空间不足 导致 Elasticsearch 分片崩溃 三个节点现在为红色 两个节点已恢复 它们的状态为黄色 ES 的 CPU 利用率为 150 内存利用率很高 正在尝试恢复它们 但似乎存在一些版本匹配冲突 我清理了磁盘空间并删除了分片的
  • 如何在弹性搜索中生成多个布尔查询的查询

    我想使用 spring 框架在 elasticsearch 中动态生成多个布尔运算的查询 我在elasticsearch中的数据就像 masterID
  • 随着索引和文档数量恒定,elasticsearch 批量索引会随着时间的推移而变慢

    我遇到了使用 NET NEST 客户端和 ElasticSearch 进行批量索引的性能随着时间的推移 索引数量和文档数量恒定而降低的情况 我们正在奔跑ElasticSearch Version 0 19 11 JVM 23 5 b02在具
  • 局部敏感哈希 - Elasticsearch

    有没有允许在 Elasticsearch 上使用 LSH 的插件 如果是的话 您能否指出该位置并告诉我如何使用它 谢谢 编辑 我发现ES使用了MinHash插件 我怎样才能用这个来比较文件呢 查找重复项的最佳设置是什么 有一个Elastic
  • 从 App Engine 连接到 Kubernetes 引擎

    我们希望使用应用程序引擎灵活的流程来更新位于 Google Kubernetes Engine 上的 ElasticSearch 索引 我们需要通过 http s 地址连接到 ElasticSearch 推荐的方法是什么 我们不想将集群暴露
  • 如何在不更改设置的情况下不区分大小写排序

    我的索引名称是 data new 下面是插入索引的代码 test id 1 name A professor Bill Cage accounting id 2 name AB professor Gregg Payne engineeri
  • 在弹性搜索中使用 GET/POST 时的不同结果

    我正在通过 Elastic Search Head 插件尝试弹性搜索 当我通过 POST 提交查询时 结果符合预期 但是 当我使用 GET 尝试相同的查询时 我总是会返回索引中的所有值 那么 如何通过 GET 将查询传递到弹性搜索服务器 以
  • Elasticsearch 单个字段的多个分析器

    我使用严格的预定义映射将不同类型的文档存储在单个索引中 它们都有一些字段 例如 body 但我希望在索引时对它们进行稍微不同的分析 例如 对特定文档使用不同的标记过滤器 并在搜索时以相同的方式处理 据我所知 分析器不能按文档指定 我还考虑使
  • 在 ElasticSearch API 应用程序中找不到 NodeBuilder

    我正在尝试实现 Elasticsearch API 我的系统接受 nodeBuilder 时出现错误 这是代码 import org elasticsearch action index IndexResponse import org e
  • 无法使用 java 8 在 Windows 10 上安装 elasticsearch 5.1.1

    我正在尝试在安装了 java 8 111 的 Windows 10 笔记本电脑上安装 ElasticSearch 5 1 1 当我尝试安装 Elastic search 时触发错误 C Users 用户名 Downloads elastic
  • 在 Elasticsearch 中删除文件后回收磁盘空间

    当我从 Elasticsearch 中删除文档时 为什么我的 总大小 保持不变 尽管由于没有以前存储的数据而明显小得多 我读过有关索引优化的内容 但我不确定这是什么或如何做到这一点 Thanks 我确信 SO 和 Google 上都有大量与
  • ElasticSearch 映射对分组文档进行折叠/执行操作的结果

    有一个对话列表 每个对话都有一个消息列表 每条消息都有不同的字段和action场地 我们需要考虑到在对话的第一条消息中使用了动作A 在几条消息之后有使用的动作A 1过了一会儿A 1 1等等 有一个聊天机器人意图列表 对对话的消息操作进行分组
  • 为 Logstash 中的新字段设置 Elasticsearch Analyzer

    通过使用GROK filter 我们可以向Logstash添加新字段 但是 我想知道如何为该特定字段设置分析器 例如 我有一个新的 id 字段 其中有一个字段 例如a b 但是 Elasticsearch 附带的普通分析器会将其分解为a a
  • Elasticsearch 无法写入日志文件

    我想激活 elasticsearch 的日志 当我运行 elasticsearch 二进制文件时 我意识到我在日志记录方面遇到问题 无法加载配置 这是输出 sudo usr share elasticsearch bin elasticse
  • 自动完成建议中的输出字段

    当我想在 elasticsearch 中索引文档时 会发生此问题 message MapperParsingException failed to parse nested IllegalArgumentException unknown

随机推荐

  • OpenMAX学习资料收集

    OpenMAX框架拆解与实现 OpenMax OMX 开发入门 OpenMax人口 OpenMAX IL spec手册下载 https www khronos org files openmax il spec 1 0 pdf OpenMA
  • 重要思想总结

    重要思想总结 求二进制序列中1的个数 检测num中某一位是0还是1 不创建临时变量交换值 判断数值的位数 判断数值的位数 获取数值的每一位数 把一个整数的二进制位的奇数位和偶数位交换 将个位数 十位数 百位数 组成一个完整的数 找素数 将秒
  • centos dhcp服务器文件,centos dhcp服务器配置

    centos dhcp服务器配置 内容精选 换一换 简要介绍PHP FPM PHP FastCGI Process Manager PHP FastCGI进程管理器 用于管理PHP进程池的软件 用于接受web服务器的请求 PHP FPM提供
  • Django错误(1146,Table 'xxxx.django_session' doesn't exist")

    原文链接 https blog csdn net BlackListMan article details 82620144 出现这种错误先检查 数据库连接设置是否成功 在setting py同级文件中的 init py 中是否添加了数据库
  • SecureCRT遇到打开错误的时候

    我的解决办法 因为我用的是安装版的 我的操作是 1 删除注册表 可查 2 关闭所有的关于securecrt的进程 通过 任务管理器 的 详细信息 仔细检查关闭 3 一般就搞定了 4 参考文档 http blog csdn net lishe
  • MyBatis Plus多表联查方法

    MyBatis Plus是一款针对MyBatis框架的增强工具 它提供了很多方便的方法来实现多表联查 你可以使用MyBatis Plus的selectPage方法来实现多表联查 该方法接收一个QueryWrapper参数 你可以在Query
  • keyCode键盘码

    下次记不住了来查查吧 keyCode 8 BackSpace BackSpace keyCode 9 Tab Tab keyCode 12 Clear keyCode 13 Enter keyCode 16 Shift L keyCode
  • linux启动kvm虚拟机,如何在Linux中使用KVM(基于内核的虚拟机)创建虚拟机 - 第1部分...

    使用KVM在Linux中创建虚拟机 第1部分 本教程讨论KVM介绍 部署以及如何使用它在RedHat为基础的分布 如RHEL CentOS7和Fedora 21来创建虚拟机 什么是KVM KVM或 基于内核的虚拟机 是面向Linux的英特尔
  • git 恢复本地代码到仓库版本_Repo和Git 版本管理常用命令总结

    1 服务器版本下载 repo init u git 192 168 1 11 i700t 60501010 platform manifest git b froyo almond m M76XXTSNCJNLYA60501010 xml
  • Vue2学习第六篇:事件处理

    一 事件的基本使用 1 使用v on xxx 或 xxx 绑定事件 其中xxx是事件名 2 事件的回调需要配置在methods对象中 最终会在vm上 3 methods中配置的函数 不要用箭头函数 否则this就不是vm了 4 method
  • 【C++初阶】仿函数和priority_queue的模拟实现(附源码)

    一 仿函数 仿函数 顾名思义就是模仿函数 它其实是一个类 类里面重载了运算符 在调用这个重载的运算符时 让我们感觉是调用函数一样 可以说相当于C语言里的函数指针一样 但是函数指针的可读性不好 不如仿函数 仿函数的特点 1 仿函数即使定义相同
  • 4.1.3 英文单词的分割符验证

    在英文文本中 各个英文单词被分隔符所分开 这些分隔符包括英文标点符号 空白字符等 其中 英文标点符号比较多 如 逗号 点号 问号 冒号 分号 单引号 感叹号 双引号 连接号 破折号 省略号 小括号 中括号 大括号 所有格符号 等 在英文文本
  • python中的并行处理(多线程)几种方式(Pool, Parallel, threading)

    1 Pool from multiprocessing import Pool import os def worker arg print begin s str arg if name main po Pool 10 定义进程池 最大进
  • Android系统apps之Setting的修改和设置

    由于接到了一个修改系统app Settings条目是需求 接着也看到了一个博主的文章http blog csdn net wangjinyu501 article details 22077803 这篇文章写的很好 基本满足了需求 我这里再
  • 《暗时间》阅读笔记一

    推荐阅读原著 https book douban com subject 6709809 https book douban com subject 6709809
  • Bert: Pre-training of Deep Bidirectional Transformers for Language Understanding

    Abstract 我们介绍了一种语言表达模型称为BERT 也就是Transformer的双边编码表示 与当前语言表达模型不同 Peters et al 2018a Radford et al 2018 BERT设计通过考虑所有层左右上下文对
  • Erlang in Mac OSX

    download the source package from the erlang website http www erlang org download html and unzip it tar zxvf otp src R14B
  • 第十届蓝桥杯省赛C++B组 迷宫

    试题 E 迷宫 本题总分 15 分 问题描述 下图给出了一个迷宫的平面图 其中标记为 1 的为障碍 标记为 0 的为可 以通行的地方 010000 000100 001001 110000 迷宫的入口为左上角 出口为右下角 在迷宫中 只能从
  • 攻防世界weak_auth知识详解

    1 进入环境 当我们点进去的时候 出来一个网页 让我们输入username和password 先随便输入一下 然后弹出是说让我们用admin作为username登入 那我们就按照它的要求吧 进行修改 这次它只是提醒了密码错误 我们的重心开始
  • Es_算分函数使用详情

    算分函数查询 相关性计算 当我们利用match查询时 文档结果会根据与搜索词条的关联度打分 score 返回结果时按照分值降序排列 例如 我们搜索 虹桥如家 结果如下 score 17 850193 source name 虹桥如家酒店真不