Lucene 索引文件的生成(二十二)之nvd&&nvm

在执行flush()的过程中,Lucene会将内存中的索引信息生成索引文件,本篇文章继续介绍索引文件.nvd&&.nvm,其生成的时机点如下图红色框标注:

图1:

  图1的流程图属于Lucene 7.5.0,在Lucene 8.4.0中同样适用,该流程图为flush()过程中的一个流程点,详情见文章文档提交之flush(二)

  生成索引文件.nvd&&.nvm的目的在于存储normValue值以及文档号,我们先了解下在索引阶段(index phase),Lucene是如何计算、收集normValue值的。

计算文档的normValue值

  在文章查询原理(四)中介绍打分公式时我们知道,计算一篇文档的分数时会考虑一个norm值,该值描述的是文档长度对打分的影响,并且norm值是通过cache[ ](数组长度为256)数组获得的,而normValue则是作为该数组的下标值。

  normValue的全名为normalization value,标准化的值,通过Lucene中的SmallFloat.intToByte4(int numTerms)方法生成一个标准化的值,该方法的参数numTerms描述的是文档的长度,文档的长度的计算方式取决于不同的打分公式,我们以默认的打分公式BM25为例展开介绍:

图2:

  图2中先计算出numTerms,然后通过SmallFloat.intToByte4方法生成一个标准化的值,即normValue。

  由图2可知numTerms共有三种计算方式:

  • 119行代码:一篇文档中包含某个域的域值数量(去重,即重复的域值不纳入域值数量)
  • 123行代码:一篇文档中包含某个域的域值数量(非去重)
  • 121行代码:非去重的域值数量 与 state.getNumOverlap()的差值,该方法的含义在介绍分词会展开

  注意的是在索引阶段,每处理一篇文档,会计算文档中每个域对应的文档长度,因为在查询阶段,无法知道会用哪个域作为查询条件。

  为什么要执行标准化的操作

  由numTerms的计算方式可以看出,如果直接采用numTerms,会造成突兀的域值数量对打分公式产生显著的影响,故需要通过SmallFloat.intToByte4方法平缓该影响,该方法的返回值为byte类型,类似归一化操作,该方法将文档长度标准化到[0, 255]的取值区间,即computerNorm的返回值的取值范围为[0, 255]。

收集文档的normValue值

  同其他索引文件一样,每个域都会各自收集normValue值,对应在源码中,每个域都会对应生成一个NormValuesWriter来实现收集。

  收集的过程中主要收集文档号跟normValue,其中文档号使用DocsWithFieldSet对象收集,该对象的处理逻辑见文章索引文件的生成(十五)之dvm&&dvd,另外使用PackedLongValues对象收集normValue值,该对象的介绍见文章PackedInts(一)

生成索引文件.nvd&&.nvm

  由于之前介绍过了其他索引文件的生成过程,相比较下来索引文件.nvd&&.nvm的生成过程过于简单并且雷同,所以就不写了。。。

结语

  对于该索引文件的内容在随后介绍索引文件.doc、pos、pay的读取的文章中会顺便提及。

点击下载附件

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值