Lucene 源码系列——pos pay 索引文件

  position 在 Lucene 中描述的是一个 term 在一篇文档中的位置,并且存在一个或多个 position。

  payload 是一个自定义的元数据(mete data)来描述 term 的某个属性,term 在一篇文章中的多个位置可以一一对应多个 payload,也可以只有部分位置带有 payload。

  offset 是一对整数值(a pair of integers),即 startOffset 跟 endOffset,它们分别描述了 term 的第一个字符跟最后一个在文档中的位置。

  每一个 term 在所有文档中的 position、payload、offset 信息在 IndexWriter.addDocument()的过程中计算出来,在内存中生成一张倒排表,最终持久化到磁盘时,通过读取倒排表,将 position 信息写入到。pos 文件中,将 payload、offset 信息写入到。pay 文件中。

  本文介绍的是索引文件。pos、.pay 的数据结构,其生成过程见文章索引文件的生成(二)

pay 文件的数据结构

图 1:

1.png

  在。pay 文件中,TermPayload、TermOffset 分别记录一个 term 的 payload、offset 信息。

TermPayload

图 2:

2.png

PackedPayBlock

每次处理一个term的128个position信息,就会将对应的128个payload信息(不一定每个position都对应一个payload)处理为一个PackedPayBlock。即除了最后一个PackedPayBlock,其他PackedPayBlock中都包含了当前term的128个payload信息。在后面的内容中,都默认PackedPayBlock中包含了128个payload信息。

PackedPayLengthBlock

PackedPayLengthBlock存放了128个payload的长度数据,并且使用了PackedInts进行了压缩存储。

这里注意是由于每一个 payload 的长度无法保证递增,只能使用 PackedInts 存储原始数据。

SumPayLength

SumPayLength存放了这128个payload的数据长度(字节数),在读取.pay文件用来确定128个payload的真实数据在.pay中的数据区间。

PayData

PayData中存放了128个payload的真实数据。

  注意的是,payload 的真实数据没有使用压缩存储。



TermOffset

图 3:

3.png

PackedOffsetBlock

跟TermPayload一样的是,都是每次处理一个term的128个position信息后,就会将对应的128个offset信息处理为一个block。

PackedOffsetStartDeltaBlock

offset是一对整数值(a pair of integers),startOffset跟endOffset分别描述了term的第一个字符跟最后一个在文档中的位置。PackedOffsetStartDeltaBlock存放了128个offset的startOffset值,并且使用了PackedInts进行压缩存储,由于这128个startOffset是个递增的值,所以实际存放了相邻两个offset的startOffset的差值。

PackedOffsetLengthBlock

PackedOffsetLengthBlock存放了128个offset的startOffset跟endOffset差值,同样使用PackedInts进行压缩存储。

pos 文件的数据结构

图 4:

4.png

  在。pos 文件中,TermPosition 记录一个 term 的 position 信息。

TermPosition

图 5:

5.png

PackedPosBlock

每次处理一个term的128个position信息,就会将这些position处理为一个PackedPosBlock。

PackedPosDeltaBlock

PackedPosDeltaBlock存放了128个位置信息,计算相邻两个position的差值后,利用PackedInts压缩存储。

VIntBlocks && VIntBlock

如果position的个数不足128个,那么将每一个position处理为一个VIntBlock。(比如说某个term有200个position,那么前128个position处理为一个PackedPosBlock,剩余的72个position处理为72个VIntBlock,72个VIntBlock为一个VIntBlocks)。

PositionDelta

term的position信息,这是一个差值。PositionDelta的最后一位用来标识当前position是否有payload信息。

PayloadLength

当前position对应的payload信息的长度,在读取.pos时,用来确定往后读取的一个字节区间。

PayloadData

当前position对应的payload真实数据。

OffsetDelta

当前position对应的offset的startOffset值,同样是个差值

OffsetLength

当前position对应的offset的endOffset与startOffset的差值。

多个域的 pay 文件的数据结构

图 6:

6.png

多个域的 pos 文件的数据结构

图 7:

7.png

结语

  .pos、.pay、.doc、.tim、.tip 文件都是在 flush()阶段通过读取倒排表一起生成的,另外.doc 跟。pos、.pay 文件还有映射关系,在后面介绍.doc 文件时候会涉及。


本文地址:https://www.6aiq.com/article/1586739443409
本文版权归作者和AIQ共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出