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