Elasticsearch搜索之explain评分分析
Lucene的IndexSearcher提供一个explain方法,能够解释Document的Score是怎么得来的,具体每一部分的得分都可以详细地打印出来。这里用一个中文实例来纯手工验算一遍Lucene的评分算法,并且结合Lucene的源码做一个解释。
首先是测试用例,我使用“北京东路”来检索一个含有address域的文档。
然后是是输出,注意它有缩进,代表一个个的层级,下面以测试环境数据作为举例:
{
|
这个看起来可真是头疼,尝试解释一下:
首先,需要学习Lucene的评分计算公式——

分值计算方式为查询语句q中每个项t与文档d的匹配分值之和,当然还有权重的因素。其中每一项的意思如下表所示:
|
表3.5 |
评分公式中的因子 |
|
评分因子 |
描 述 |
|
tf(t in d) |
项频率因子——文档(d)中出现项(t)的频率 |
|
idf(t) |
项在倒排文档中出现的频率:它被用来衡量项的“唯一”性.出现频率较高的term具有较低的idf,出现较少的term具有较高的idf |
|
boost(t.field in d) |
域和文档的加权,在索引期间设置.你可以用该方法 对某个域或文档进行静态单独加权 |
|
lengthNorm(t.field in d) |
域的归一化(Normalization)值,表示域中包含的项数量.该值在索引期间计算,并保存在索引norm中.对于该因子,更短的域(或更少的语汇单元)能获得更大的加权 |
|
coord(q,d) |
协调因子(Coordination factor),基于文档中包含查询的项个数.该因子会对包含更多搜索项的文档进行类似AND的加权 |
|
queryNorm(q) |
每个査询的归一化值,指毎个查询项权重的平方和 |
总匹配分值的计算
具体到上面的测试来讲,地址字段address匹配了二个词条,先分别计算每个词条对应的分值,然后相加,最后结果= ("北京") 0.43069553+ (“东路”)0.29647252=0.7271681 (结果舍入)。
查询语句在某个field匹配分值计算
这个0.43069553是如何来的呢?这是词条“北京”在field中的分值=查询权重queryWeight * 域权重fieldWeight 即 0.34374008*1.2529687=0.43069553。
同埋“东路”这个词条在field中的分值=查询权重queryWeight * 域权重fieldWeight 即 0.2851919*1.0395545=0.29647252
queryWeight的计算
queryWeight的计算可以在TermQuery$TermWeight.normalize(float)方法中看到计算的实现:
public void normalize(float queryNorm) {
this.queryNorm = queryNorm;
//原来queryWeight 为idf*t.getBoost(),现在为queryNorm*idf*t.getBoost()。
queryWeight *= queryNorm;
value = queryWeight * idf;
}
其实默认情况下,queryWeight = idf * queryNorm,因为Lucene中默认的boost = 1.0。
以“北京”这个词条为例,查询权重queryWeight = idf * queryNorm,即 0.34374008 = 5.0118747*0.06858513。
idf的计算
idf是项在倒排文档中出现的频率,计算方式为
/** Implemented as <code>log(numDocs/(docFreq+1)) + 1</code>. */
@Overrid
public float idf(long docFreq, long numDocs) {
return (float)(Math.log(numDocs/(double)(docFreq+1)) + 1.0);
}
docFreq是根据指定关键字进行检索,检索到的Document的数量,我们测试“北京”词条的docFreq=2104;
numDocs是指索引文件中总共的Document的数量,对应explain结果中的maxDocs,我们测试的maxDocs=116302。
用计算器验证一下,没有错误,这里就不啰嗦了。
fieldWeight的计算
fieldWeight = tf * idf * fieldNorm
tf和idf的计算参考前面的,fieldNorm的计算在索引的时候确定了,此时直接从索引文件中读取,这个方法并没有给出直接的计算。
如果使用DefaultSimilarity的话,它实际上就是lengthNorm,域越长的话Norm越小,在org/apache/lucene/search/similarities/DefaultSimilarity.java里面有关于它的计算:
public float lengthNorm(FieldInvertState state) {
final int numTerms;
if (discountOverlaps)
numTerms = state.getLength() - state.getNumOverlap();
else
numTerms = state.getLength();
return state.getBoost() * ((float) (1.0 / Math.sqrt(numTerms)));
}
这个我就不再验算了,每个域的Terms数量开方求倒数乘以该域的boost得出最终的结果。
Elasticsearch搜索之explain评分分析的更多相关文章
- ElasticSearch评分分析 explian 解释和一些查询理解
ElasticSearch评分分析 explian 解释和一些查询理解 按照es-ik分析器安装了ik分词器.创建索引:PUT /index_ik_test.索引包含2个字段:content和nick ...
- Elasticsearch系列---常见搜索方式与聚合分析
概要 本篇主要介绍常见的6种搜索方式.聚合分析语法,基本是上机实战,可以和关系型数据库作对比,如果之前了解关系型数据库,那本篇只需要了解搜索和聚合的语法规则就可以了. 搜索响应报文 以上篇建立的mus ...
- wukong引擎源码分析之索引——part 3 文档评分 无非就是将docid对应的fields信息存储起来,为搜索结果rank评分用
之前的文章分析过,接受索引请求处理的代码在segmenter_worker.go里: func (engine *Engine) segmenterWorker() { for { request : ...
- 看完这篇还不会 Elasticsearch 搜索,那我就哭了!
本文主要介绍 ElasticSearch 搜索相关的知识,首先会介绍下 URI Search 和 Request Body Search,同时也会学习什么是搜索的相关性,如何衡量相关性. Search ...
- ElasticSearch搜索介绍四
ElasticSearch搜索 最基础的搜索: curl -XGET http://localhost:9200/_search 返回的结果为: { "took": 2, &quo ...
- Elasticsearch搜索资料汇总
Elasticsearch 简介 Elasticsearch(ES)是一个基于Lucene 构建的开源分布式搜索分析引擎,可以近实时的索引.检索数据.具备高可靠.易使用.社区活跃等特点,在全文检索.日 ...
- 一次 ElasticSearch 搜索优化
一次 ElasticSearch 搜索优化 1. 环境 ES6.3.2,索引名称 user_v1,5个主分片,每个分片一个副本.分片基本都在11GB左右,GET _cat/shards/user 一共 ...
- Elasticsearch搜索结果返回不一致问题
一.背景 这周在使用Elasticsearch搜索的时候遇到一个,对于同一个搜索请求,会出现top50返回结果和排序不一致的问题.那么为什么会出现这样的问题? 后来通过百度和google,发现这是因为 ...
- ElasticStack学习(六):ElasticSearch搜索初探
一.ElasticSearch搜索介绍 1.ElasticSearch搜索方式主要分为以下两种: 1).URI Search:此种查询主要是使用Http的Get方法,在URL中使用查询参数进行查询: ...
随机推荐
- Spring框架(4)---AOP讲解铺垫
AOP讲解铺垫 不得不说,刚开始去理解这个Aop是有点难理解的,主要还是新的概念比较多,对于初学者一下子不一定马上能够快速吸收,所以我先对什么事Aop做一个解释: 首先说明:本文不是自己所写 ...
- Java集合ArrayList源码解读
最近在回顾数据结构,想到JDK这样好的代码资源不利用有点可惜,这是第一篇,花了心思.篇幅有点长,希望想看的朋友认真看下去,提出宝贵的意见. :) 内部原理 ArrayList 的3个字段 priva ...
- commonJS的核心思想
服务器端的 Node.js 遵循 CommonJS规范,该规范的核心思想是允许模块通过 require 方法来同步加载所要依赖的其他模块,然后通过 exports 或 module.exports 来 ...
- HTTP请求错误400、401、402、403、404、405、406、407、412、414、500、501、502解析
HTTP 错误 400 400 请求出错 由于语法格式有误,服务器无法理解此请求.不作修改,客户程序就无法重复此请求. HTTP 错误 401 401.1 未授权:登录失败 此错误表明传输给服务器的证 ...
- IDEA使用心得-----懒得截图了,但是大家应该看得懂
1.界面设置,有白色和 黑色风格两种,我个人喜欢黑色风格,护眼最重要的是看着帅. 设置方法:FILE--Settings--Editor--Colors&Fonts--Scheme name ...
- 使sublimetext3在ubuntu下可以打中文和在windows的dos命令行下正常显示中文
学习闲暇之余,总结一下在windows和ubuntu下使用sublimetext3遇到的问题 一.关于sublimetext3在windows的dos命令行下不能编译运行中文的解决方案: 因为dos命 ...
- php流程管理练习
今天我们做一个流程管理: 1.流程管理的用法是什么样的? 2.怎么发起想要的流程? 3.审批的人要是怎么审批通过? 4.流程审核是不是要挨个走过? 一. 做这个流程管理肯定要有数据库: 二.数据库结束 ...
- 车大棒浅谈jQuery源码(一)
背景 因为最近辞职找工作,投了许多家公司.结果简历要么石沉大海,一点音讯都没有,要么就是邮件回复说不匹配.后面加了一些QQ群,才发现原来我工作经验年限太少了.现在深圳都是3经验起步,北京据说更加恐怖. ...
- iOS开发之Run Loop
1.概述 (1) Run Loop提供了一种异步执行代码的机制,不能并行执行任务. (2) 在主队列中,Main Run Loop直接配合任务的执行,负责处理UI事件.计时器,以及其它内核相关事件. ...
- css——样式表分类,选择器
一,样式表分类 (1)内联样式[优先级最高][常用][代码重复使用性最差] (当特殊的样式需要应用到个别元素时,就可以使用内联样式. 使用内联样式的方法是在相关的标签中使用样式属性.样式属性可以包含任 ...