Lucene的IndexSearcher提供一个explain方法,能够解释Document的Score是怎么得来的,具体每一部分的得分都可以详细地打印出来。这里用一个中文实例来纯手工验算一遍Lucene的评分算法,并且结合Lucene的源码做一个解释。

首先是测试用例,我使用“北京东路”来检索一个含有address域的文档。

然后是是输出,注意它有缩进,代表一个个的层级,下面以测试环境数据作为举例:

{

"value" : 0.7271681,

"description" : "max of:",

"details" : [ {

"value" : 0.7271681,

"description" : "sum of:",

"details" : [ {

"value" : 0.43069553,

"description" : "weight(address:北京 in 787) [PerFieldSimilarity], result of:",

"details" : [ {

"value" : 0.43069553,

"description" : "score(doc=787,freq=1.0), product of:",

"details" : [ {

"value" : 0.34374008,

"description" : "queryWeight, product of:",

"details" : [ {

"value" : 5.0118747,

"description" : "idf(docFreq=2104, maxDocs=116302)"

}, {

"value" : 0.06858513,

"description" : "queryNorm"

} ]

}, {

"value" : 1.2529687,

"description" : "fieldWeight in 787, product of:",

"details" : [ {

"value" : 1.0,

"description" : "tf(freq=1.0), with freq of:",

"details" : [ {

"value" : 1.0,

"description" : "termFreq=1.0"

} ]

}, {

"value" : 5.0118747,

"description" : "idf(docFreq=2104, maxDocs=116302)"

}, {

"value" : 0.25,

"description" : "fieldNorm(doc=787)"

} ]

} ]

} ]

}, {

"value" : 0.29647252,

"description" : "weight(address:东路 in 787) [PerFieldSimilarity], result of:",

"details" : [ {

"value" : 0.29647252,

"description" : "score(doc=787,freq=1.0), product of:",

"details" : [ {

"value" : 0.2851919,

"description" : "queryWeight, product of:",

"details" : [ {

"value" : 4.158218,

"description" : "idf(docFreq=4942, maxDocs=116302)"

}, {

"value" : 0.06858513,

"description" : "queryNorm"

} ]

}, {

"value" : 1.0395545,

"description" : "fieldWeight in 787, product of:",

"details" : [ {

"value" : 1.0,

"description" : "tf(freq=1.0), with freq of:",

"details" : [ {

"value" : 1.0,

"description" : "termFreq=1.0"

} ]

}, {

"value" : 4.158218,

"description" : "idf(docFreq=4942, maxDocs=116302)"

}, {

"value" : 0.25,

"description" : "fieldNorm(doc=787)"

} ]

} ]

} ]

} ]

} ]

}

这个看起来可真是头疼,尝试解释一下:

首先,需要学习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)方法中看到计算的实现:

publicvoidnormalize(floatqueryNorm){

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 log(numDocs/(docFreq+1)) + 1. */

@Overrid

publicfloatidf(longdocFreq,longnumDocs){

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里面有关于它的计算:

publicfloatlengthNorm(FieldInvertStatestate){

finalintnumTerms;

if(discountOverlaps)

numTerms =state.getLength()-state.getNumOverlap();

else

numTerms =state.getLength();

returnstate.getBoost()*((float)(1.0/Math.sqrt(numTerms)));

}

这个我就不再验算了,每个域的Terms数量开方求倒数乘以该域的boost得出最终的结果。

elasticsearch 打分 源码_Elasticsearch搜索之explain评分分析相关推荐

  1. ElasticSearch.js源码走一个大概

    介绍 Elasticsearch 是一个分布式可扩展的实时搜索和分析引擎,一个建立在全文搜索引擎 Apache Lucene(TM) 基础上的搜索引擎.当然 Elasticsearch 并不仅仅是 L ...

  2. via浏览器简洁主页html源码 支持搜索提示

    简介: via浏览器简洁主页源码支持搜索提示,扒的一个简洁好看的via浏览器主页源码,纯html+js无后端源码分享给大家,放到服务器即可运行. 网盘下载地址: http://kekewl.cc/AL ...

  3. Elasticsearch CCR源码分析(补充)

    接上篇TODO Elasticsearch CCR源码分析 上篇TODO: http请求(ccr/follow)接收到后,follow集群节点开始全量同步,是以snapshot的模式去拉leader集 ...

  4. 直播网站程序源码,搜索框实现快速搜索功能

    直播网站程序源码,搜索框实现快速搜索功能 module.exports = async function (params, context) {const db = context.databasec ...

  5. 抖音SEO优化源码,搜索排名系统,技术理论分析,抖音矩阵,抖音seo系统。

    前言:抖音SEO优化源码,搜索排名系统,技术理论分析,抖音矩阵,抖音seo系统.抖音seo矩阵系统底层框架上支持了ai视频混剪,视频产出,视频AI制作,多账号多平台矩阵,视频一键内部分发,站内实现搜索 ...

  6. 分析开源项目源码,我们该如何入手分析?(授人以渔)

    点击上方 好好学java ,选择 星标 公众号 重磅资讯.干货,第一时间送达 今日推荐:牛人 20000 字的 Spring Cloud 总结,太硬核了~ 1 前言 本文接上篇文章跟大家聊聊我们为什么 ...

  7. elasticsearch _field_stats 源码分析

    _field_stats 实现的功能:https://www.elastic.co/guide/en/elasticsearch/reference/5.6/search-field-stats.ht ...

  8. 2款在线FM音乐聚合播放PHP源码 带搜索

    简介: MKOnlineMusicPlayer 是一款开源的基于 Meting 的在线音乐播放器.具有音乐搜索.播放.下载.歌词同步显示.个人某易云音乐播放列表同步等功能.前端界面参照 QQ 音乐网页 ...

  9. 搜索 php源码,影视搜索php源码

    调用尘落影视网的资源,也可自行替换 源码如下:<?php header("Content-type: text/html; charset=utf-8"); $movie=$ ...

最新文章

  1. sql server 2008 修改sa密码
  2. Linux Shell编程入门
  3. 【Thymeleaf】格式化日期
  4. poj 1845 Sumdiv (算数基本定理+逆元)
  5. 获取PE文件的区段表
  6. java 向上抛异常_java throws 向上抛出的概念问题
  7. helm安装postgres_添加到postgres数据库外的keycloak k8s helm chart环境参数
  8. 搭建MSSM框架(Maven+Spring+Spring MVC+MyBatis)
  9. lisp提取长方形坐标_语义SLAM | 深度学习用于特征提取 : SuperPoint(一)
  10. linux转为root用户_[R] 展示linux文件树 - collapsibleTree
  11. 好用的MessageFormat类
  12. 2017-2018-2 20179205 《网络攻防技术与实践》第八周作业
  13. 编译lzlib mysql5.6_CentOS下编译安装MySQL5.6
  14. 遗传算法求解立体仓库货位优化
  15. 服务器pe安装win7系统安装教程,pe安装win7原版镜像系统教程
  16. python生成拼音
  17. docker image 重命名
  18. 鸿蒙会出电脑系统吗,鸿蒙有没有可能出PC操作系统?
  19. apigateway-kong(二)admin-api(结合实例比官网还详细)
  20. 计算机二级选择题笔记百度云,计算机二级题库及计算机二级ms office 复习笔记.doc...

热门文章

  1. 前端常用的几种加密方法
  2. Python中使用正则表达式以及正则表达式匹配规则
  3. 微信小程序详细图文教程-10分钟完成微信小程序开发部署发布 小程序趟过的坑,你遇到几个??
  4. Java数组(Array)
  5. ES8388说明书CC1110F32RHHR 低功耗 1 GHz 无线芯片
  6. 12月编程语言排行榜,java跌至低点,低代码发展迅猛
  7. IOT专用IOP平台
  8. Python之输入一个年份判断该年是否是闰年
  9. 【XJTUSE计算机图形学】第三章 几何造型技术(1)——参数曲线和曲面
  10. 为什么一个电子商务网站需要七秒钟加载?