官网介绍:Lucene- Index File Formats
索引层次结构
Lucene的索引结构主要分为以下几个层次:
- 索引(Index)
一个索引对应一个索引目录(文件夹)。 - 段(Segment)
- 一个索引可以包含多个段,段之间是相互独立的,可以被分开搜索,不同的段可以合并。
- 有相同前缀如
_0
或_1
的文件属于同一个段。 segments.gen
和segments_N
是段的元数据文件。
- 文档(Document)
- 文档是建索引的基本单位,一个段可以包含多个文档。
- 新添加的文档是单独保存在一个新生成的段中,随着段的合并,不同的文档合并到一个段中。
- 域(Field)
- 一篇文档包含不同类型的信息,可以分开索引,保存在不同的域中。
- 不同域的索引方式可以不同。
- 词(Term)
词是索引的最小单位,是经过词法分析和语言处理后的字符串。(如果两个 Term 的 text 内容一样,但是分属不同的 Field,被认为是不同的 Term)
Field类型
- 存储域(Stored Field)
存储域的文本不会进行索引,也就不会被进行 tokenized 等操作,一般可以用于那些不希望被检索的信息,但是可以随着其他域的检索而一起返回。 - 索引域(Indexed Field)
索引域的文本会被 tokenized 从而被索引,可以用于检索。
Segment
每个段包含的信息:
- Field names
索引中的域名信息。 - Stored Field values
- Term dictionary
词典包含索引中的所有 term 以及term的文档频率、指向 term frequency 和 proximity data 的指针。 - Term Frequency data
term 在相应文档中的 TF 信息。 - Term Proximity data
term 在相应文档中的 position 信息。 - Normalization factors
For each field in each document, a value is stored that is multiplied into the score for hits on that field. - Term Vectors
有时也成为(document vector),包含 term text 和 tf。 - Deleted documents
用于记录哪些 document 被删除了。
File Extensions
Name | Extension | Description |
---|---|---|
Segments File | segments.gen, segments_N | 段的元数据:索引有多少个段,每个段有多少篇文档 |
Lock File | write.lock | 用于阻止多个 IndexWriter 操作同一索引 |
Compound Files | .cfs | 可选的文件,包含一些经常用的文件 |
Field Infos | .fnm | 存储域相关的信息:保存了此段包含了多少域,每个域的名称以及索引方式 |
Field Index | .fdx | 存储了指向每个文档的 field data 的指针 |
Field Data | .fdt | 保存每个文档的 stored field |
Term Infos | .tis | 存储 term info,term根据 term’s field name 和 term text 进行字母排序 |
Term Info Index | .tii | Term Infos文件的索引(跳表,IndexInterval),用于random access to ‘.tis’ file |
Frequencies | .frq | 存储 term 的文档列表,以及term在相应文档的 tf |
Positions | .prx | 存储 term 在相应文档中的位置信息 |
Norms | .nrm | docs和fields的编码长度和 boost factors |
Term Vector Index | .tvx | 保存每个文档在 document data(.tvd) 和 field data(.tvf) 中的 offset |
Term Vector Documents | .tvd | 保存每个文档的: the number of fields, a list of the fields with term vector info,以及一个指针指向 .tvf 文件中的域信息 |
Term Vector Fields | .tvf | 保存了每个域的 term vector(term列表, term’s frequncies, position and offset信息) |
Deleted Documents | .del | 记录被删的文档信息 |
正向信息
Index -> Document -> Field -> Term
相关的文件:
segments_N
保存了索引包含多少个段,每个段多少篇文档。.fnm
保存了此段包含多少个域,每个域的名称及索引方式。fdx
、fdt
保存了此段包含的所有文档,每篇文档包含了多少域,每个域保存了哪些信息。tvx
、tvd
、tvf
。
保存了此段包含多少文档,每篇文档包含了多少个域,每个域包含了多少词,每个词的信息。
反向信息
Term -> Document
相关的文件:
.tis
、tii
保存了词典,term 根据字典顺序排序。.frq
保存了倒排表,即包含每个 term 的文档 ID 列表,prx
保存了倒排表中每个词在包含此词的文档中的位置。
基本类型
- Byte
最基本的类型,8位bit。 - UInt32
4个Byte。 - UInt64
8个Byte。 - VInt
变长的整型,每个 Byte 的最高 1 位表示是否还有另一个 Byte(0表示没有,1表示有),后 7 位表示数值。越前面的 Byte 表示数值的低位,越后面的 Byte 表示数值的高位。 - Chars
utf-8编码的一系列 Byte。 - String
一个字符串首先是一个 VInt 来表示所包含的字符个数,接着是 utf-8 编码的字符序列 Chars。
基本规则
规则的目的:减小存储空间,加快访问速度。
前缀后缀规则(Prefix + Suffix)
首先前提是 Term Dictionary 中所有的 Term 是按照字典顺序进行排列的,采用前缀后缀规则,当某个词和前一个词有共同前缀的时候,后面的词仅仅保存前缀在词中偏移(offset),以及除前缀以外的字符串(后缀)。
eg:存储词 term, termagancy, termagant, terminal
正常的方式存储(35个Byte):[VInt=4] [term], [VInt=10] [termagancy], [VInt=9] [termagant], [VInt=8] [terminal]。
前缀后缀规则(22个Byte):[VInt=4] [term], [VInt=4(offset)] [VInt=6] [agency], [VInt=8(offset)] [VInt=1] [t], [VInt=4(offset)] [VInt=4] [inal]。
差值规则(Delta)
在倒排索引中,需要保存很多整型数字的信息,比如文档 ID 号, Term的位置等(在索引中都是按从小到大的顺序排列)。
当数字增大时,每个数字占用的 Byte 的个数也随之增多。
差值规则:就是先后保存两个整数的时候,后面的整数仅仅保存和前面整数的差即可。
eg:存储数字 (5, 9, 11) 时,可以存储为 (5, 4, 2)。
或然跟随规则(A, B?)
索引结构中存在这一的情况:某个值 A 后面可能存在某个值 B,需要一个标志来表示后面是否跟随 B。
如果在 A 后面放一个 Byte 来存储标志会造成空间浪费。将 A 的值左移一位,空出最后一位作为标志位,空间将为 1 Bit。(当大量存在这种情况时,这个规则可以有效减小存储空间。)
跳表规则(Skip List)
跳表这种结构主要是为了提高查找的性能。
- 元素是按顺序排列的。
- 存在跳跃间隔(Interval)。Lucene中间隔为两个元素索引之间的差值。
- 跳表是有层次(Level)的,每层间隔不同。Lucene中层次从0开始计数,且计数不包括原链表。
感谢:
http://www.cnblogs.com/forfuture1978/archive/2009/12/14/1623597.html