Lucene (v4.5) 深入学习 (二) —— 文件结构

相比2.X的Lucene,4.X里增加了不少文件,而且内部的数据结构面目全非,看着相当纠结。

各种文件信息的具体格式是这篇文档最关键的部分,同时也是之后理解代码的钥匙。因为整个Lucene的工作其实就是创建,操作和使用这些文件。下表是从官网上找来的文件列表。

NAMEEXTENSIONBRIEF DESCRIPTION
Segments File segments.gen, segments_N 存储提交时的信息
Lock File write.lock 防止多个IndexWriter写同一个文件
Segment Info .si 存储段的元数据信息
Compound File .cfs, .cfe 一个可选的“虚拟”文件,实际上包含了所有其他索引文件。目的是应对使用文件句柄的系统,防止句柄数量过多。
Fields .fnm 存储域的信息(元数据?)
Field Index .fdx 包含指向域数据的指针
Field Data .fdt 存储域数据
Term Dictionary .tim 字典,存储了term的信息
Term Index .tip 字典的索引
Frequencies .doc 存储了term在文档中的频率信息
Positions .pos 存储了term在索引中的位置信息
Payloads .pay 存储附加到每个位置的元数据信息,如字符偏移量和用户的自定义信息(?)
Norms .nvd, .nvm 存储了编码了的文档和域的长度和影响因子
Per-Document Values .dvd, .dvm 存储编码了的附加的评分因子或其他类型的文档信息
Term Vector Index .tvx 存储term在文档中的偏移量
Term Vector Documents .tvd 存储每篇文档包含的term向量
Term Vector Fields .tvf 存储term向量的域级别(?)信息
Deleted Documents .del 存储被删除文档的信息

在实际使用中,根据索引合并策略,默认会对其中大部分文件进行合并,最后会生成类似下图的文件结构。
索引文件结构

具体格式

segments_N ,segments.gen

segments.gen: GenHeader, Generation, Generation
segments_N结构见下图
segments_N

  • Header记录了版本数字和用以标识文件的字符串。示意图中不会特意加入这个变量。这个变量在之后会反复出现,忽略介绍。
  • Version记录了索引被更改的次数。更改操作包括添加和删除。
  • NameCounter用于生成新的段文件的名字。
  • SegCount记录所包含的段的数量。
  • SegName是段的名字,同时用于同一个段的所有索引文件的文件名前缀。
  • DelGen记录段执行删除文件操作的次数。
  • DeletionCount记录段中被删除(标记为删除)的文件的数量。
  • Checksum用来验证打开的索引文件的完整性。
  • SegCodec段的编解码器的名字。
  • CommitUserData存储一个用户提供的不透明的Map<String,String>结构给IndexWriter.setCommitData(java.util.Map)(暂时不知道其作用)
  • FieldInfosGen记录段生成(?)fieldInfos文件的次数。
  • UpdatesFiles存储在段中更新过的文件的列表。

write.lock

如果write.lock文件存在,那么说明当前有一个writer正在修改index。这个锁文件确保同一时间只有一个writer修改Index。

.si

.si结构见下图
.si

  • SegVersion是段所基于的Lucene的版本。
  • SegSize段所包含的文档数。
  • IsCompoundFile记录了这个段是不是复合的。(这个还不太理解,可能是“合并过的”的意思。不过那样的话似乎应该用“merge”)如果值是-1则不是,1则是。
  • Checksum用于确认文件的完整性。
  • The Diagnostics Map作为调试工具由IndexWriter自己(私有地)为每个段创建。它包含了像Lucene的版本,OS信息,Java的版本,段创建的原因(合并,从内存生成,添加索引等)等元信息。
  • Attributes编解码器自己的属性,是一个Map。
  • Files是段所包括的文件列表。

.cfs, .cfe

.cfs结构见下图
.cfs
.cfe结构见下图
.cfe

  • FileData就是这个段所包含的(原始)文件。

.fnm

.fnm结构见下图
.fnm

  • FieldsCount文件(段)中所包含的域的数量。
  • FieldName域的名字(一个UTF-8的字符串)。
  • FieldNumber域的数量。注意相比于之前版本的Lucene,这个版本的域的数量不是隐含在它们的顺序编号中,而是显式地给出。
  • FieldBits一个字节,包括了域的各种选项(可选特征)。(从低位开始)
    1.  标志这个域是否是索引的。1表示需要索引,0表示不需要索引。
    2.  标志这个域是否有term向量。1表示有,0表示没有。
    3.  标志偏移量是否设置。如果是1则在位置后添加偏移量。
    4.  没有使用。Fourth bit is unused.
    5.  如果设置,这个(索引)域忽略标准化。
    6.  如果设置,则用户的有效荷载(payload)会被储存在这个域。
    7.  如果设置,term的频率和位置会被忽略。
    8.  如果设置,term的位置会被忽略。
  • DocValuesBits(一个字节)记录了每个文档的值类型。低位的四个bit表示DocValues的可选特征,高位的四个bit则表示了标准化的可选特征。其中DocValues的选择包括:
    •  0: 这个域没有DocValues
    •  1: NumericDocValues. (FieldInfo.DocValuesType.NUMERIC)
    •  2: BinaryDocValues. (DocValuesType#BINARY)
    •  3: SortedDocValues. (DocValuesType#SORTED)
  • DocValuesGen表示DocValues的代数。如果是-1,表示这个域没有更新DocValues。
  • Attributes编解码器自己的属性,是一个Map。

.fdt

.fdt结构见下图
.fdt

  • PackedIntsVersion :PackedInts.VERSION_CURRENT(VInt)暂时不知道具体做什么。
  • ChunkCount的值事先是不知道的。这个值表示段中存储所有文档所需要的Chunk数。
  • Chunk 包括了DocBase, ChunkDocs, DocFieldCounts, DocLengths,
    DocBase这个Chunk中第一篇文档的ID(VInt)。
    ChunkDocs 这个Chunk中所包含的文档数(VInt)。
    DocFieldCounts 这个Chunk中所包含的每一个文档所包含的域的数量,具体编码方式为:

     

    •   如果chunkDocs=1,也就是说这个Chunk中只有一篇文档,那么这个值就是这篇文档的域的数量,并被编码为VInt
    •   否则则读取一个VInt(这里称为bitsRequired)。如果bitsRequired是0,那么所有文档的域的数量都是一样的,并且具体数值等于下一个(接下来)的VInt的值。否则bitsRequired是可以用来存储任何值的bit的数目,并且这些值被存储在一个包装好的队列(array)中,在这个队列中每个值的长度都是bitsRequired个bit。
  • DocLengths这个Chunk中所有文档的长度,编码方式同DocFieldCounts。
  • Compressed Docs一个压缩了的,使用LZ4。
  • 一共有ChunkDocs 个ChunkDocs
  • FieldNumAndType一个VLong型量。其中最后三位表示Type,其他的位则是FieldNum。
    FieldNum:域的ID
    Type:

     

    • 0: String
    • 1: BinaryValue
    • 2: Int
    • 3: Float
    • 4: Long
    • 5: Double
    • 6, 7: 未使用
  • Value也就是具体的值,值的类型依据Type。其中BinaryValue的格式为:
    • BinaryValue –> ValueLength ValueLength

.fdx

.fdx:Header, ChunkIndex
.fdx,ChunkIndex的结构可以见CompressingStoredFieldsIndexWriter。比较复杂,如有时间再把内容翻译出来。

2014-3-25:继续学习过程中发现要把.tim,.tip讲得更清楚些还需要补充不少东西,于是决定在这篇里把这两个文件的相关内容去掉,在下一篇中深入讨论。

 

posted @ 2016-05-04 17:28  XGogo  阅读(731)  评论(0)    收藏  举报