Lucene 的索引文件结构

Lucene的索引文件存在一个索引目录中。文件共有10种:.f(n),.fdt,.fdx,.fnm,.frq,.prx,.tii,.tis,deletable,seqments.下面分别描述。

几个文件格式中常用的数据类型。

VInt:可变长度的整数,最小一个字节,可以是2-4个字节,如果一个字节表示不了的话。不过通常是一个字节就够了。

Vlong:可变长度的长整数,最小一个字节,可以是2-8个字节,如果一个字节表示不了的话。不过通常是一个字节就够了。

VString:java中的字符串是没有像C里面一样的’\0’的结束符的,所以在文件中记录一个字符串时,在字符串前放一个VInt表示字符串的长度。数据类型

Int,4个字节的整数。

Long,8个字节的整数。

1.segments文件:用来表示索引文件的名字和Document的个数。在SegmentInfos.java描述,参见write()文件头中的第1个4Byte是SegmentName,在Lucene中,SegmentName是一个16进制的数字,是上面的如*.fnm中的*部分,每新增加一个Document,SegmentName会加1(做的是SegmentName++的动作),所以此部分的值会比实际的SegmentName大1。文件头中的第2个4Byte是索引文件的个数,Lucene支持在一个目录中存放多个索引文件(这一部分我也不是十分清楚,不知道哪位大哥可以解惑)。文件体中是一个可重复的部分,重复的次数由文件头中的第2部分的大小决定。可重复的部分包括2个部分:SegmentName和该索引文件中包含的Document个数。(从这里可以看出,在Lucene中,单个索引文件最多可以包含2的32方个文件(4个byte)

2..frm文件:用来保存FieldName,注意,此文件只保存非切分部分的Field,如通过Filed.text()方法进行切分后的Field保存在.tii,*.tis中。

具体格式如下:(在FieldInfos.java描述,参见write())

文件头中的FieldNum代表索引的Field的个数。文件体中描述每个Field的信息,个数与文件体中的FieldNum相同。每个Field的信息包括2个部分:FieldName,索引的Field的名字,Flag表示该Field是否是索引的(indexed)。0×00表示未索引,0×01表示索引。

3.*.fdt文件,用于存放Field的值,每个Document是连续存放的,每个Document内部的格式如下:(参看FieldsWriter.java文件的addDocument()函数)

头部中的FieldNum是该Document中选择了存储的Field的个数(field.isStroed()==true),内容体中每个Filed中包括3个部分。

Pos:该Field在Document的顺序,是第几个Field

Flag:该Field是否是一个Token(field.isToken()==true)

Value:该Field的值

4.*.fdx文件,用于存放每个Document在fdt文件中的偏移。

每个Document中记录的是一个Long型的整数,代表*.fdt文件中每个Document的偏移(起点-1)

5.*.tis文件,用于存放切分过的Field中的值。(参看2,fnm文件)文件格式参看TermInfosWriter.java文件中的add()函数)文件头中的TermNum是一个4byte的Int,代表Term的个文件体是每个Term的重复。每个Term包括7个域。

Start:该Term的偏移

Content:该Term的值

FieldPos:该Term出现的顺序,即是第几个Field

Freq:该Term出现的频率

FreqPointer:Rreq在*.frq文件中的偏移

ProxPointer:Prox在*.prx文件中的偏移

IndexPointer:Index在*.tii文件中的偏移(我不敢确定),该项是可选项,只在isIndex==true是出现。(不明白这个的意思,isIndex指什么)也可以参看SegmentTermEnum.java中的next()函数,这是一个读单个term的函数。

6.deletable文件,用来存放被删除的文件名。文件格式参看IndexWriter.java中的readDeleteableFiles()函数)文件体中是一个4byte的整数,代表被删除的文件个数文件体中是一组被删除的文件名。还有*.f(n)是存放Norm的文件,.tii是与.tis相对的,.frq(存放词频的文件),.prx(存放词频的位置的文件,与*.frq文件联合使用.