索引文件格式概述

官网介绍:Lucene- Index File Formats

索引层次结构

Lucene的索引结构主要分为以下几个层次:

  1. 索引(Index)
    一个索引对应一个索引目录(文件夹)。
  2. 段(Segment)
    • 一个索引可以包含多个段,段之间是相互独立的,可以被分开搜索,不同的段可以合并。
    • 有相同前缀如_0_1的文件属于同一个段。
    • segments.gensegments_N是段的元数据文件。
  3. 文档(Document)
    • 文档是建索引的基本单位,一个段可以包含多个文档。
    • 新添加的文档是单独保存在一个新生成的段中,随着段的合并,不同的文档合并到一个段中。
  4. 域(Field)
    • 一篇文档包含不同类型的信息,可以分开索引,保存在不同的域中。
    • 不同域的索引方式可以不同。
  5. 词(Term)
    词是索引的最小单位,是经过词法分析和语言处理后的字符串。(如果两个 Term 的 text 内容一样,但是分属不同的 Field,被认为是不同的 Term)

Field类型

  1. 存储域(Stored Field)
    存储域的文本不会进行索引,也就不会被进行 tokenized 等操作,一般可以用于那些不希望被检索的信息,但是可以随着其他域的检索而一起返回。
  2. 索引域(Indexed Field)
    索引域的文本会被 tokenized 从而被索引,可以用于检索。

Segment

每个段包含的信息:

  1. Field names
    索引中的域名信息。
  2. Stored Field values
  3. Term dictionary
    词典包含索引中的所有 term 以及term的文档频率、指向 term frequency 和 proximity data 的指针。
  4. Term Frequency data
    term 在相应文档中的 TF 信息。
  5. Term Proximity data
    term 在相应文档中的 position 信息。
  6. Normalization factors
    For each field in each document, a value is stored that is multiplied into the score for hits on that field.
  7. Term Vectors
    有时也成为(document vector),包含 term text 和 tf。
  8. 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
    保存了此段包含多少个域,每个域的名称及索引方式。
  • fdxfdt
    保存了此段包含的所有文档,每篇文档包含了多少域,每个域保存了哪些信息。
  • tvxtvdtvf
    保存了此段包含多少文档,每篇文档包含了多少个域,每个域包含了多少词,每个词的信息。

反向信息

Term -> Document

相关的文件:

  • .tistii
    保存了词典,term 根据字典顺序排序。
  • .frq
    保存了倒排表,即包含每个 term 的文档 ID 列表,
  • prx
    保存了倒排表中每个词在包含此词的文档中的位置。

基本类型

  1. Byte
    最基本的类型,8位bit。
  2. UInt32
    4个Byte。
  3. UInt64
    8个Byte。
  4. VInt
    变长的整型,每个 Byte 的最高 1 位表示是否还有另一个 Byte(0表示没有,1表示有),后 7 位表示数值。越前面的 Byte 表示数值的低位,越后面的 Byte 表示数值的高位。
  5. Chars
    utf-8编码的一系列 Byte。
  6. 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