Lucene doc 文件格式详解
2019-10-11 本文已影响0人
ni_d58f
本文及后面关于Lucene的文章所采用的lucene 版本为8.1.0.
1. 什么是doc文件
doc
文件主要用于保存term的倒排表信息,包括docId倒排链及term在docId的term freq信息等。倒排链是Lucene 进行全文检索的核心数据结构,请特别关注这个数据结构
2. doc文件格式
doc文件格式.png3. 测试代码与结果
请参考Lucene tim文件格式详解 第三部分
4. 范例doc文件内容
doc文件.png5. doc文件内容分析
5.1 文件头
文件头部分主要内容为标识此文件类型为Lucene50PostingsWriterDoc
, 源码部分在Lucene50PostingsWriter
的123行,主要内容如下
-
3fd7 6c17
固定头MAGIC -
19
为Lucene50PostingsWriterDoc长度25 -
4c 7563 656e 6535 3050 6f73 7469 6e67 7357 7269 7465 7244 6f63
25个字节即Lucene50PostingsWriterPos -
00 0000 01
4个字节的BlockTreeTermsReader.VERSION_CURRENT
-
836a 556d b951 0bfb cd0f dbfc f298 2299
16个字节的segmentId, 这个是随机生成的 -
0a
segment suffix 长度 10 -
4c75 6365 6e65 3530 5f30
10个字节的segment suffix内容即Lucene50_0
5.2 doc data 部分
开始本部分阅读时,请注意一个在第3部分得到的结果及含义, 现在开始分析该部分内容
-
02
PackedInts.VERSION_CURRENT 值2, 源码在ForUtil
的100行 -
2021 0223 0405 0607 0809 0a0b 0c0d 0e0f 1011 1213 1415 1617 1819 1a1b 1c1d 1e1f
32字节的FormatAndBits
, 具体逻辑在ForUtil
的106行。 关于这个字段的作用暂时没有搞明白
下面为term的doc信息。 主要逻辑是: 对于term的doc freq = 1的term来说,doc文件不保存这个term的doc信息,而是在tim
文件中保存,doc 文件只保存doc freq > 1的term。在范例中,只有nice的doc freq > 1, 故只保存nice的doc倒排链
-
000203
其中0002
中的00
= 0 << 1,02
为doc中nice的term freq,03
= 1 << 1 + 1, 这里具体计算逻
辑在
...
final int singletonDocID;
if (state.docFreq == 1) {
// pulse the singleton docid into the term dictionary, freq is implicitly totalTermFreq
singletonDocID = docDeltaBuffer[0];
} else {
singletonDocID = -1;
// vInt encode the remaining doc deltas and freqs:
for(int i=0;i<docBufferUpto;i++) {
final int docDelta = docDeltaBuffer[i]; //delta编码
final int freq = freqBuffer[i];
if (!writeFreqs) {
docOut.writeVInt(docDelta);
} else if (freqBuffer[i] == 1) {
docOut.writeVInt((docDelta<<1)|1);
} else {
docOut.writeVInt(docDelta<<1);
docOut.writeVInt(freq);
}
}
}
...
0<<1
,1 << 1
0 代表doc 0, 实际编码的时候会以128个doc为一个block进行编码, 组内将docId以delta编码。假设现在有doc1, doc2, doc5, doc6, 编码则主1,1,3,1
关于其它term(term freq = 1)的编码方式,请参考tim
文件相应的格式内容
5.3 footer区
footer区主要有以下内容
-
c0 2893 e8
MAGIC值,为header值的反码 -
00 0000 00
固定4个字节int 值为0 -
00 0000 00f8 a1d5 52
8个字节的CRC码
觉得本文有帮助的话,请关注我的简书,一同进步!