简介
本文介绍了Lucene6.6.1版本的索引文件格式,如果你想看其他的版本可以去Lucene官网上寻找(http://lucene.apache.org/core/)。
定义
索引,文档,域,词项是Lucene的基本概念。
一个索引包含一系列的文档。
- 一个文档是一系列的域组成的。
- 一个域是被命名的一系列词项。
- 一个词项是一系列的字节组成的
两组相同的字节,但属于不同的域,那么这两组字节被认为是不同的词项。因此词项为了区分都是包含两个内容的:域名,词项的内容。
倒排索引
索引存储了词项的统计信息用来提升基于词项查询的效率。Lucene的索引属于倒排索引,因为它能够根据词项来列出包含该词项的所有文档。这与通常情况下通过文档查询词项的方式刚好相反。
域的类型
在Lucene中,域能够被存储,这时域的文本内容将被原原本本地保存在索引中,而不是建立倒排索引。如果域的内容建立了倒排索引,我们称这个域被索引了。一个域既可以被存储也可以被索引。
域的文本内容被索引时,即可以被切分成多个词项后建立索引,也可以不切分直接建立索引。一般情况下域是需要被切分的,不过有些时候我们也会用到一些不切分建索引的域。
段
Lucene的索引可以由多个子索引组成,我们称这些子索引为段。每个段都是一个独立的索引,都可以被单独查询。建立索引的的过程包括以下两个步骤:
- 为新添加进来的文档创建新的段
- 合并已有的段
对Lucene的查询可以覆盖多个段甚至多个索引,每个索引可能包含一组段。
文档编号
Lucene用整数类型的文档编号来表示每个文档。第一个被添加进索引的文档的编号是0,后续添加的的文档编号按1递增。
需要注意的是文档编号是会改变的,索引如果你打算把这些编号保存在Lucene之外就要谨慎行事了。特别注意在下列情况,编号会改变:
-
存储于段中的文档编码的唯一性仅仅限于所在的段中,因此这些文档编号在被更大的上下文引用之前需要进行转化。一个常规的转化方法就是给文档编码加上基础值。例如,将两个拥有5个文档的段合并。段1【0,1,2,3,4】,段2【0,1,2,3,4】。转化的时候给段1中的编码加上基础值0,给段2的编码加上基础值5,转化后如下:段1【0,1,2,3,4】,段2【5,6,7,8,9】。
-
当文档被删除后,原本的文档编码序列就会出现缺口。这些缺口最终会通过段合并消除。被删除的文档也会在段合并之后被彻底丢弃。合并过后的生产的新段的文档序列将不会有缺口。
索引结构概览
每个段索引都维护着如下结构:
-
Segment info.记录着段的元数据信息,比如文档数量,用到了哪些文件,
-
Field names. 记录着索引的域名集合.
-
Stored Field values. 记录着每个文档的键值对,键是域的名称,值是域的值。它保存了所有存储类型的域的数据。
-
Term dictionary. 记录着被索引域中的所有词项,同时记录着拥有该词项的文档数量,以及指向词频和词项位置的指针.
-
Term Frequency data. 对于每个词项,记录拥有该词项的文档的数量,该词项在一个文档中出现的频率。
-
Term Proximity data. 对于每个词项,记录该词项出现在每个文档中的位置信息。
-
Normalization factors. 对于在每个文档中的每个域,记录一个值,这个值会与查询的score相乘。
-
Term Vectors. 由词项内容和词项频率组成。
-
Per-document values. lucene的docvalues文件,即数据的列式存储,用作聚合和排序。
-
Live documents. 记录着还存活的文档(与被删除对应)
-
Point values.记录着点位信息的索引域,可以用于数值类型范围过滤,像BigInteger或BigDecimal这样的大数处理。
文件命名
所有属于同一个段的文件都拥有着相同的文件名和各种各样的后缀名。这些后缀名对应着下面描述的不同的文件格式。当使用混合文件格式的时候,这些文件都将合并到.cfs文件中。
所有的属于同一个索引的段都存储于同一个目录下。
Lucene中的文件名要求永远不会被重复使用。也就是说,当任何文件要被保存在目录下时,它的文件名必须是之前没被使用过的。实现这个要求的方法就是给文件名加上数字。比如,第一个段文件名是segments_1,接着是segments_2,以此类推。
文件后缀的总结
下表总结了Lucene中文件名称和后缀
Name | Extension | Segments File |
---|---|---|
Segments File | segments_N | 保存提交点的信息 |
Lock File | write.lock | 写文件锁,用于防止多个IndexWriters同时写一个文件 |
Segment Info | .si | 保存段的元数据信息 |
Compound File | .cfs, .cfe | 采用混合格式下该文件包括其他所有格式的文件 |
Fields | .fnm | 保存域信息 |
Field Index | .fdx | 保存指向域数据的指针 |
Field Data | .fdt | 保存域数据 |
Term Dictionary | .tim | 保存词项信息 |
Term Index | .tip | Term Dictionary的索引信息 |
Frequencies | .doc | 记录文档信息,以及文档中词项对应的词频 |
Positions | .pos | 记录词项的位置信息 |
Payloads | .pay | 全文索引的字段,使用了一些像payloads的高级特性会有该文件,保存了term在doc中的一些高级特性 |
Norms | .nvd, .nvm | 文件保存索引字段加权数据 |
Per-Document Values | .dvd, .dvm | lucene的docvalues文件,即数据的列式存储,用作聚合和排序 |
Term Vector Index | .tvx | 记录文档数据记录中的偏移量 |
Term Vector Documents | .tvd | 记录有词项向量的文档的信息 |
Term Vector Fields | .tvf | 词项向量的域级别信息 |
Live Documents | .liv | 存活文件的信息 |
Point values | .dii, .dim | 记录被索引的点 |
文件锁
写文件锁被命名为write.lock,默认存储于索引目录下。它保证了同一时间只能有一个IndexWriter修改索引。