本来没有这篇文章,在公司分享ES的时候遇到一个问题,使用boost的时候,怎么从评分score中知道boost的影响。

虽然我们从查询结果可以直观看到,boost起了应有的作用,但是在explain的时候,找了很久也不明白,boost去哪了?

这个问题花了点时间,不过还是挺值得。由于没有直接用过lucene,也从没想过到lucene网站上去看文档。在Elastic的文档中发现这样一段描述

In fact, reading the explain output is a little more complex than that. You won’t see the boost value or t.getBoost() mentioned in the explanation at all. Instead, the boost is rolled into the queryNorm that is applied to a particular term. Although we said that the queryNorm is the same for every term, you will see that the queryNorm for a boosted term is higher than the queryNorm for an unboosted term.

大概是说:从explain中寻找boost是有点复杂的,因为它被放到queryNorm的计算当中了

queryNorm是怎么计算的?

首先我们应该很容易在explain计算idf的部分看到queryNorm。而计算queryNorm的方式是在底部序号为1的lucene的参考资料中。

计算公式如下:

从这里可以看出我们还需要一个公式

有了这两个公式,我们就可以计算queryNorm,而queryNorm中融合了t.getBoost()这就是我们所关心Boost。显然Boost不是简单的乘上了某个倍数,所以我们很难直观的从score中看到,评分被乘了10或者20,也是我们在分享的时候,找了半天,也没有找到一个整数倍数的原因。

在Elasticsearch 中queryNorm是怎么计算的?

虽然我们有了公式,不过利用公式带入到我们的查询参数中会发现,数值还是有点偏差,有一些细节在公式中并没有体现。通过实验(非源码)我大概能了解计算方式,这里我就举一个实际例子来看ES怎么计算queryNorm。

首先设计一条查询语句,这里不讨论idf的计算,设计的查询中idf都是1

{
"size":30,
"query":{
"bool": {
"should": [
{
"match": {
"name": {
"query": "便宜了",
"boost": 1
}
}
},
{
"match": {
"server": {
"query": "电信",
"boost": 1
}
}
}
]
}
}
}

这是一个bool查询,(Lucene (and thus Elasticsearch) uses the Boolean model to find matching documents,我们的很多查询其实都被看做bool查询,ES只是提供了比较友好的其他查询方式,比如terms查询就是一种bool的should查询,或者直观一点,就是or条件查询)。boost都是1,默认的boost也是1。根据公式,我们按照每个字一个词进行分词的情况下,一共搜索了5个字,计算queryNorm的方式如下:

1/Math.sqrt(5) = 0.4472136

符合我们的预期,如果我们修改boost呢?

{
"size":30,
"query":{
"bool": {
"should": [
{
"match": {
"name": {
"query": "便宜了",
"boost": 4
}
}
},
{
"match": {
"server": {
"query": "电信",
"boost": 1
}
}
}
]
}
}
}

按照公式t.getBoost() 在计算“便宜了” 三个字的时候,应该要乘以4,计算公式应该是

1/Math.sqrt((1 * 4)^2 * 3 + 2 * 1) =0.1414213

但实际情况并非如此,其实ES在处理这个时候,如果较大的boost命中,es将小的那个值变成了0.25,也就是4分之一

1/Math.sqrt(3 + 2 * (1 * 0.25)^2) = 0.5656854

反过来如果,较大的boost没有命中,就会放大较大的boost的影响,采用第一个算法取用 0.1414213,所以如果有两个文档分别命中:

  • name命中, 无论server是否命中,采用0.5656854
  • name无命中, server命中,采用,0.1414213

两个数相除正好是4倍左右,可以看到,如果字数差距再大一些,倍数可能不是4,会有一定偏差

note:以上分析结果基于试验,ES和lucene源码不一定是这样实现,毕竟公式可以各种变化计算来达到4倍差值。

参考资料:

  1. http://lucene.apache.org/core/4_6_0/core/org/apache/lucene/search/similarities/TFIDFSimilarity.html
  2. https://www.elastic.co/guide/en/elasticsearch/guide/current/scoring-theory.html#field-norm

Elasticsearch 评分score计算中的Boost 和 queryNorm的更多相关文章

  1. Elasticsearch学习笔记(十四)relevance score相关性评分的计算(1)

    一.多shard场景下relevance score不准确问题     1.问题描述:            多个shard下,如果每个shard包含指定搜索条件的document数量不均匀的情况下, ...

  2. elasticsearch relevance score相关性评分的计算

    一.多shard场景下relevance score不准确问题 1.问题描述: 多个shard下,如果每个shard包含指定搜索条件的document数量不均匀的情况下,会导致在某个shard上doc ...

  3. ElasticSearch 评分排序

    背景 通过脚本改变评分 背景 近期有一个需求,需要对优惠券可用商品列表加个排序,只针对面值类的券不包括折扣券. 需求是这样的,假设有一张面值券 50 块钱,可用商品列表 A 100.B 40.C 10 ...

  4. ElasticSearch评分分析 explian 解释和一些查询理解

    ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.创建索引:PUT /index_ik_test.索引包含2个字段:content和nick ...

  5. WOE:信用评分卡模型中的变量离散化方法(生存分析)

    WOE:信用评分卡模型中的变量离散化方法 2016-03-21 生存分析 在做回归模型时,因临床需要常常需要对连续性的变量离散化,诸如年龄,分为老.中.青三组,一般的做法是ROC或者X-tile等等. ...

  6. 【主流技术】ElasticSearch 在 Spring 项目中的实践

    前言 ElasticSearch简称es,是一个开源的高扩展的分布式全文检索引擎. 它可以近乎实时的存储.检索数据,其扩展性很好,ElasticSearch是企业级应用中较为常见的技术. 下面和大家分 ...

  7. 如何在VS2013中进行Boost单元测试

    对于如何在VS2013中进行Boost单元测试,这方面资料太少.自己也因此走了不少弯路.下文将会阐述一下如何在VS2013中进行Boost单元测试. 在开始Boost单元测试之前,我们需要先安装VS2 ...

  8. ES 02 - 部署Elasticsearch单机服务 + 部署中的常见问题

    目录 1 准备工作 1.1 安装JDK 1.2 下载安装包 1.3 创建elastic用户 2 启动ES服务 2.1 修改配置文件 2.2 启动服务 3 验证ES服务是否可用 4 关闭与重启服务 4. ...

  9. FPGA计算中定标与位扩展的实现

    我不知道名字取对没有,在FPGA计算中有时往往需要在不溢出的情况下将数扩大,从而获得更好的计算精度. 比如.在一个8位宽的系统中,将x=0000_0010,算术左移m=5位之后得到xt=0100_00 ...

随机推荐

  1. 搭建Hadoop2.6.0+Spark1.1.0集群环境

    前几篇文章主要介绍了单机模式的hadoop和spark的安装和配置,方便开发和调试.本文主要介绍,真正集群环境下hadoop和spark的安装和使用. 1. 环境准备 集群有三台机器: master: ...

  2. chromium之ref_counted

    namespace subtle { class RefCountedBase { protected: RefCountedBase(); ~RefCountedBase(); void AddRe ...

  3. .Net 上传文件到ftp服务器和下载文件

    突然发现又很久没有写博客了,想起哎呦,还是写一篇博客记录一下吧,虽然自己还是那个渣渣猿. 最近在做上传文件的功能,上传到ftp文件服务器有利于管理上传文件. 前面的博客有写到layui如何上传文件,然 ...

  4. MySQL 5.7增强半同步测试

            we've know the machenism of semi-synchronous replication in my previous article,let's do som ...

  5. Spring总结以及在面试中的一些问题

    Spring总结以及在面试中的一些问题. 1.谈谈你对spring IOC和DI的理解,它们有什么区别? IoC Inverse of Control 反转控制的概念,就是将原本在程序中手动创建Use ...

  6. ActivatedRoute 当前激活的路由对象

    ActivatedRoute,当前激活的路由对象,主要用于保存路由,获取路由传递的参数. 一:传递参数的三种方式,以及ActivatedRoute获取他们的方式: 1.在查询参数中传递数据: /pro ...

  7. Delphi Math单元函数

    本文转至http://blog.sina.com.cn/s/blog_976ba8a501010vvf.html 这个单元包含高性能的算术.三角.对数.统计和金融方面的计算及FPU程序函数用于补充De ...

  8. hadoop生态搭建(3节点)-14.redis配置

    # ==================================================================规划node1 redis:7000 7001 192.168. ...

  9. 10种简单的Java性能优化

    你是否正打算优化hashCode()方法?是否想要绕开正则表达式?Lukas Eder介绍了很多简单方便的性能优化小贴士以及扩展程序性能的技巧. 最近“全网域(Web Scale)”一词被炒得火热,人 ...

  10. ChipScope Pro Inserter - "ERROR:NgdBuild:924 - bidirect pad net '<oDRAM0_A>' is driving non-buffer primitives

    解决方案: Using a IOBUF signal as a trigger for the ILA Inserter flow will cause a NGDBuild error. These ...