segments.gen和segments_N保存了段的元数据信息,索引有多少个段,每个段有多少篇文档。而段的真正的数据信息是保存在域(Field)和词(Term)中的。
一个索引只有一个segments.gen,而segments_N可能有多个。
IndexReader.open() -> DirectoryReader.open() -> FindSegmentsFile.run() FindSegmentsFile.doBody() -> SegmentInfos.read()
相关辅助类:ChecksumIndexInput
DirectoryReader
通过调用FindSegmentsFile查找应该打开的segmentFileName,然后再调用SegmentInfos.read()去读取段的元数据。
|
|
SegmentInfos
FindSegmentsFile.run()
以下步骤是确定打开哪个segments_N文件。
- 得到 genA
listAll所有索引目录文件,通过SegmentInfos.getCurrentSegmentGeneration(files);得到genA,基本逻辑是查找segments开头的文件并选择 N 最大的一个作为genA。 - 得到 genB
通过IndexInput的子类读取segments.gen文件,该文件中保存了version、gen1和gen2几个值,如果version正确,则比较gen1和gen2,两个相等则为genB。 - 得到 N
选择genA和genB中最大的一个作为 N。
确定了segments_N文件名后就调用FindSegmentsFile.doBody()方法,其实现调用了SegmentInfos.read(directory, segmentFileName)去读取具体的segments_N文件。
SegmentInfos.read()
- 获取 IndexInput 实例
通过new ChecksumIndexInput(directory.openInput(segmentFileName))得到input实例, - 读取 format, version, counter, segCount
| 属性 | 描述 |
|——–|——–|
|format|索引文件格式的版本号,主要是校验 IndexWriter 和 IndexReader 是否使用了同一个版本号。|
|version|索引的版本号,记录了 IndexWriter 将修改提交到索引文件中的次数。可以比较 IndexReader 中的 version 和索引文件中的 version 是否相同来判断此 IndexReader 被打开后,还有没有被 IndexWriter 更新。|
|counter|是下一个新段的段名。|
|segCount|段的个数。| - 读取每个段的元数据
SegmentInfos.read() 123for (int i = input.readInt(); i > 0; i--) { // read segmentInfosadd(new SegmentInfo(directory, format, input));}
| 属性 | 描述 |
|---|---|
| segName | 存储段名。 |
| segSize | 存储段中包含的文档数。 |
| delGen | .del文件的版本号,每当 IndexWriter 向索引提交删除操作的时候,加1。 |
| docStoreOffset | 标志位,域和词向量的存储方式,-1 表示单独存储,否则表示共享存储。 |
| docStoreSegment | 保存了共享段的名字。 |
| docStoreIsCompoundFile | doc是否存储在 Compound File (.cfx) 文件中 |
| hasSingleNormFile | 标志位,1表示所有的 Norm Factor 都存在 .nrm 文件中,否则每个域都有自己的文件 .fN |
| numField | 域的数量 |
| normGen | 记录每个域的 norm file |
| isCompoundFile | 是否为复合文件,把同一个段中的文件按照一定的格式保存在一个文件当中,以减少每次打开文件的个数 |
| delCount | 记录了此段中删除的文档的数目 |
| hasProx | 如果至少有一个段 omitTf 为fase,也即词频需要被保存,则 hasProx 为1,否则为0 |
| diagnostics | 调试信息 |
对于域(Stored Field)和词向量(Term Vector)的存储可以有不同的方式,即可以每个段(Segment)单独存储自己的域和词向量信息,也可以多个段共享域和词向量,把它们存储到一个段中去。
- 如果
DocStoreOffset为-1,则此段单独存储自己的域和词向量,从存储文件上来看,如果此段段名为XXX,则此段有自己的XXX.fdt,XXX.fdx,XXX.tvf,XXX.tvd,XXX.tvx文件。DocStoreSegment和DocStoreIsCompoundFile在此处不被保存。 - 如果
DocStoreOffset不为-1,则DocStoreSegment保存了共享的段的名字,比如为YYY,DocStoreOffset则为此段的域及词向量信息在共享段中的偏移量。则此段没有自己的XXX.fdt,XXX.fdx,XXX.tvf,XXX.tvd,XXX.tvx文件,而是将信息存放在共享段的YYY.fdt,YYY.fdx,YYY.tvf,YYY.tvd,YYY.tvx文件中。
- 读取 userData
保存了user在 IndexWriter.commit 提交的信息。 - checkSum
存储了 segment_N 文件的校验和。
感谢:
http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623599.html