segments_N

  当IndexWriter执行commit()操作后,会生成一个segments_N文件,该文件描述了当前索引目录中所有有效的段信息文件(active segment info),即之前文章介绍的segmentInfo文件。

  索引目录中可能存在多个Segments_N文件,每个Segment_N文件代表某次commit()时的索引状态,其中N值最大的Segments_N文件代表最新的一次提交,它包含当前索引目录中所有的索引信息。

  图1中最新的一次提交生成了Segments_5文件。

图1:

  图1中Segments_N文件包含的索引信息关系如下图:

图2:

  一个索引目录中存在多个segments_N文件的原因大体分为两点:

segments_N文件的数据结构

图3:

LuceneVersion

图4:

  LuceneVersio描述了当前运行的Lucene版本,比如本文基于Lucene7.5.0写的,那么LuceneVersion的值如下:

Version

  Version描述的是创建该segment_N文件的Lucene的major值,在读取阶段,该segment_N文件可能被更高版本的Lucene读取,用来检查兼容性。

NameCounter

  NameCounter用来给新的segmentInfo文件提供名字的前缀值,例如下图中 _8 即为前缀值。

图5:

SegCount

  该字段描述了当前索引目录中的有效的段信息文件(active segment info),即.si文件的个数。

MinSegmentLuceneVersion

图6:

  索引目录中的.si文件的版本可能各不相同,MinSegmentLuceneVersion记录版本最小的,不详细展开,同图4。

SegmentInfo

图7:

  该字段描述了一个segmentInfo文件(.si文件)的信息。

SegName

  该字段描述了segmentInfo文件及对应的其他索引文件的名字前缀,图8中,下面所有的文件属于同一个segment。

图8:

SegID

  该字段描述了segmentInfo文件的一个唯一标示。

SegCodec

  该字段描述了segmentInfo文件编码值,例如"Lucene70"。

DelGen

  该字段描述了属于同一个segment的.liv文件的generation number,该值在后面介绍文档的添加、删除、更新时会给出详细含义。

DeletionCount

  该字段描述了segmentInfo文件中被删除文档的个数。

FieldInfosGen

  该字段描述了属于同一个segment的.fnm文件的generation number,当域的信息每发生一次变化,FieldInfosGen的值就会+1,比如说调用了IndexWriter.updateDocValues(..)的方法

DocValuesGen

  该字段描述了属于同一个segment的.dvm、.dvd文件的generation number, 当有调用IndexWriter.updateDocValues(..)该值就会+1,该值在后面介绍DocValues域的更新时会给出详细含义。

SoftDelCount

  该字段记录软删除的文档个数,软删除的概念后面介绍文档的添加、删除、更新时会给出详细含义。

FieldInfosFiles

  如果域的信息发生了变化(更新),那么会记录最新生成的.fnm文件。

UpdatesFiles

  记录发生变化的索引文件,比如调用了IndexWriter.updateDocValues(..)的方法后,会生成新的.dvd、.dvm文件,那么域值跟索引文件名字的信息。

图9:

  上图中,先找出包含域名为"content",域值为"c"的文档,然后更新该文档中的NumericDocValuesField域,更新域名跟域值。此操作后,会生成新的.dvd、dvm文件。

CommitUserData

  该字段可以通过调用IndexWriter.setLiveCommitData(...)来在commit()时记录自定义的信息,上文中提到,如果使用了NoDeletionPolicy,那么Lucene会保留每一次commit()时的索引文件信息作为检查点,这样我们可以通过CommitUserData跟Segment_N来回退到任意的检查点。

segments_N文件的总数据结构

图10:

结语

  至此介绍了本人在业务中接触过的所有的索引文件(复合文件没有讲…😝),完全深入理解索引文件的所有内容需要了解IndexWriter添加、删除、更新文档、出错的逻辑,而写这篇文章的另一个目的也是为介绍IndexWriter作为预备知识。

点击下载Markdown文件