美文网首页
Lucene doc 文件格式详解

Lucene doc 文件格式详解

作者: ni_d58f | 来源:发表于2019-10-11 18:18 被阅读0次

    本文及后面关于Lucene的文章所采用的lucene 版本为8.1.0.

    1. 什么是doc文件

    doc文件主要用于保存term的倒排表信息,包括docId倒排链及term在docId的term freq信息等。倒排链是Lucene 进行全文检索的核心数据结构,请特别关注这个数据结构


    2. doc文件格式

    doc文件格式.png

    3. 测试代码与结果

    请参考Lucene tim文件格式详解 第三部分


    4. 范例doc文件内容

    doc文件.png

    5. doc文件内容分析

    5.1 文件头

    文件头部分主要内容为标识此文件类型为Lucene50PostingsWriterDoc, 源码部分在Lucene50PostingsWriter的123行,主要内容如下

    1. 3fd7 6c17 固定头MAGIC
    2. 19 为Lucene50PostingsWriterDoc长度25
    3. 4c 7563 656e 6535 3050 6f73 7469 6e67 7357 7269 7465 7244 6f63 25个字节即Lucene50PostingsWriterPos
    4. 00 0000 01 4个字节的BlockTreeTermsReader.VERSION_CURRENT
    5. 836a 556d b951 0bfb cd0f dbfc f298 2299 16个字节的segmentId, 这个是随机生成的
    6. 0a segment suffix 长度 10
    7. 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码

    觉得本文有帮助的话,请关注我的简书,一同进步!

    相关文章

      网友评论

          本文标题:Lucene doc 文件格式详解

          本文链接:https://www.haomeiwen.com/subject/vpxxmctx.html