@HUST张友东 work@taobao zyd_com@126.com
分类: 服务器与存储
2010-12-03 19:18:15
花了点时间研究lucene的索引格式,测试的时候我使用的是2.9.3版本的,但由于后来版本的索引相对较复杂,我就学习了下1.4版本的索引格式,主要是参见lucene官方网站上的文档()。
1. Lucene中的基本概念
Lucene中基本的概念包括索引,文档,域,和词条。
l 索引(index)包含一系列的文档;
l 文档(document)由一系列的域组成;
l 域(field)是一系列词条的集合;
l 词条(term)是简单的字符串;
2. 索引中段(segment)的概念
Lucene的索引可能由多个子索引,或称为段组成。每个段是对应一个独立的索引,各个段能被独立的用于检索。当向加入新的文档时可能创建新的段,当索引被优化时,可能对多个段进行合并。
3. 文档编号
l 在lucene内部,每个文档拥有一个编号(docID,从0开始)用于在段内唯一标示文档,按照文档被添加到索引中的顺序依次编号。
l 文档编号并不是不变的,当索引被删除或合并时,文档的编号可能会改变。
4. Lucene中的原始类型
Byte,Uint32,Uint64,Vint(变长整型),Chars(UTF-8),String(Vint,Chars)
其中变长整型的定义为:每个字节的最高有效位标示是否还有下一个字节,并采用小尾端的表示方法。例如:
l 1表示为:00000001;(第一位0表示,该Vint到此结束)
l 130表示为:10000010 00000001;(前一个字节的1用于标示,还要继续读取下一个字节,第二个字节的0表示Vint到此结束)
5. 段描述信息文件(segments)
Segments的字段及类型信息:
l Segments --> Format, Version, SegCount,
l Format, SegCount, SegSize --> UInt32
l Version --> UInt64
l SegName --> String
Segments的字段描述信息:
l Format is -1 in Lucene 1.4;
l Version为索引被添加或删除的次数(add or delete documents from index);
l SegCount为段的数量;
l SegName为段名,用于组成该段的其他文件的文件名前缀;
l SegSize为包含在段中的文档数;
6. 锁文件(commit.lock or write.lock)
锁文件不出现在索引目录下,而是存放在对应系统的临时目录下(java.io.tmpdir)。
l 当临时目录下出现commit.lock,说明有进程在重写segments文件,或是有进程在读取segments文件。commit.lock可以防止文件在被读取时被删除。
l 当临时目录下出现write.lock,说明有进程正在往索引中添加或删除文档。write.lock可以防止多个进程同时更新索引。
7. 删除文件表(deletable)
Deletable的字段及类型信息:
l Deletable --> DeletableCount,
l DeletableCount --> UInt32
l DeletableName --> String
Deletable的字段描述信息:
l deletable中包含索引中不再用到的文件名,但这些文件名不能被删除。该信息只在Win32下使用,当文件被打开时,不能被删除。在其它操作系统平台,该文件中不包含任何信息。
8. Per-segment信息概述
l Filed names:包含索引中所有的域的信息<域名,域属性>。
l Stored Field values:对于每个文档,包含被存储的域的信息(由域的属性决定),以
l Term Dictionary:包含所有词条(前缀压缩表示)及该词条的文档频率数(多少个文档包含该词条),以及词条在文档中出现的频率及位置信息的指针。
l Term Frequency data:对于字典中的每个词条,其在所出现的文档中的频率信息(在文档中出现多少次,文档案编号排序)。
l Term Proximity data:对于字典中的每个词条,其在每隔文档中出现的位置信息。
l Normalization factors:对于被索引的每个域,每个文档拥有一个激励因子,当搜索该域文档命中时,文档的分数将会乘上该激励因子。
l Term Vectors:对于每个文档中的每个域,存储了该域的词条向量信息(包含哪些词条及对应的词条信息)。
l Deleted document:可选的文件,用位图标记文档已经被删除。
9. Per-segment文件之Field信息
Segment中的域的描述信息(名字,属性)包含在.fnm文件中。
.fnm的字段及类型信息:
l FieldInfos (.fnm) --> FieldsCount,
l FieldsCount --> VInt
l FieldName --> String
l FieldBits --> Byte
.fnm的字段描述信息:
l FieldCount:域的个数;
l FieldName:域的名字;
l FieldBits:域的描述信息(位图),如是否被索引,是否存储词条向量。
对于需要存储的域,需要xx.fdx,xx.fdt两个文件进行描述:
.fdx的字段及类型信息:
l FieldIndex (.fdx) -->
l FieldValuesPosition --> Uint64
.fdx的字段描述信息:
l FieldValuesPosition用于查找在域信息文件中查找指定的域信息。
.fdt的字段及类型信息:
l FieldData (.fdt) -->
l DocFieldData --> FieldCount,
l FieldCount --> VInt
l FieldNum --> VInt
l Bits --> Byte
l Value --> String
.fdt的字段描述信息:
l FieldCount:该文档包含的域的个数;
l FieldNum:该Field在field描述表xx.fnm中的编号;
l Bits:对应的域是被tokenized;(只有1个位被使用);
l Value:域所对应的值;
10. Per-segment文件之Term Dictionary信息
.tis的字段及类型信息:
l TermInfoFile (.tis)--> TIVersion, TermCount, IndexInterval, SkipInterval, TermInfos
l TIVersion --> UInt32
l TermCount --> UInt64
l IndexInterval --> UInt32
l SkipInterval --> UInt32
l TermInfos -->
l TermInfo -->
l Term -->
l Suffix --> String
l PrefixLength, DocFreq, FreqDelta, ProxDelta, SkipDelta--> VInt
.tis的字段描述信息:
l 文件按Term进行排序(Term的field name为主关键字,Term的text为辅关键字)。
l TIVersion为在Lucene1.4中为-2;
l TermCount为词条的个数
l 词条的前缀是共享,PrefixLength为本词条包含上一个词条的前缀长度,Suffix则为本词条的后缀。如前一个词条为“bone”,后一个词条为“boy”,则PrefixLength为2,suffix为y。FieldNum为Term所在域在xx.fdt文件中的编号。
l DocFreq为包含该Term的文档数;
l FreqDelta为Term所对应的TermFreqs在xx.frq(接下来介绍)文件中的位置。位置信息由本词条的位置与前一词条的位置的差值(如果是第一个词条,则认为其前一个词条的位置信息为0),后面带Delta的字段与此类似。
l ProxDelta为Term所对应的TermPositions在xx.prx(接下来介绍)文件中的位置。
l SkipDelta为Term所对应的SkipData在xx.frq(接下来介绍)文件中的位置。
.tii包含了.tis文件中间隔IndexInterval的项(包含项的位置信息),其结构与.tis文件非常相似,对于每条记录,多了IndexDelta信息。
.tii的字段及类型信息:
l TermInfoIndex (.tii)--> IndexTermCount, TermIndices
l IndexTermCount --> UInt32
l TermIndices -->
l IndexDelta --> VInt
.tii的字段描述信息:
l IndexDelta为Term的TermInfo在.tis文件中的位置。
11. Per-segment文件之Frequency信息
.frq文件列出了包含词条的文档,以及词条在文档中的出现频率(次数)。
.frq文件的字段及类型信息:
l FreqFile (.frq) -->
l TermFreqs -->
l TermFreq --> DocDelta, Freq?
l SkipData -->
l SkipDatum --> DocSkip,FreqSkip,ProxSkip
l DocDelta,Freq,DocSkip,FreqSkip,ProxSkip --> VInt
.frq的字段描述信息:
l TermFreqs按照term进行排序(tis文件中的顺序),TermFreqs按照词条所在文档的编号排序。
l DocDelta决定文档号以及频率信息,DocDelta/2为本次的文档号与上次文档号的差值。当DocDelta为奇数时,说明词条出现的次数为1;当DocDelta为偶数时,下一个VInt则为词条在文档中出现的频率。例如,一个词条在文档7中出现1次,在文档11中出现3次,则TermFreqs为:15,22,3 (不应该是15,8,3么,求解答?)
12. Per-segment文件之Position信息
.prx文件中包含各个词条在文档中的位置信息。
.prx文件的字段及类型信息:
l ProxFile (.prx) -->
l TermPositions -->
l Positions -->
l PositionDelta --> VInt
.prx文件的字段描述信息:
l TermPositions按照term在.tis文件中的顺序排序。
l Positions条目按照.frq中文档号升序排列。
l PositionDelta为词条文档中出现的位置与前一次在该文档出现的位置之差。
例如:Term出现在一个文档第4的位置,在另一个文档中为第5,9的位置。
则其位置信息为:4,5,4
说明:第一个4为在第一个文档中出现的位置信息,由于其为第一项位置信息,其前一项视为0;第二个5为在第二个文档中第一次出现的位置,第三个4为在第二个文档中第2次出现位置与第一次出现的位置之差。
13. Per-segment文件之信息
对于被索引的每个域,每个文档包含一个激励因子,信息存放在.f[0-9]*文件中(文件个数由被索引的域的个数决定)。
f[0-9]*的字段及类型信息:
l Norms (.f[0-9]*) -->
f[0-9]*的字段描述信息:
l 每个字节被编码为一个浮点数,0-2bit为尾数部分,3-8bit为指数部分。这些信息最终会被转换为IEEE single float表示的值。
14. Per-segment文件之Term Vector信息
对于每个文档,.tvx文件包含了指向文档数据(.tvd文件)的指针。
.tvx文件中的字段及类型信息:
l DocumentIndex (.tvx) --> TVXVersion
l TVXVersion --> Int
l DocumentPosition --> UInt64
对于每个文档,在.tvd文件中包含文档域的数目,域包含词条的信息,以及指向词条向量位置信息(.tvf文件)的指针。
.tvd文件中的字段及类型信息:
l Document (.tvd) --> TVDVersion
l TVDVersion --> Int
l NumFields --> VInt
l FieldNums -->
l FieldNumDelta --> VInt
l FieldPositions -->
l FieldPosition --> VLong
.tvd文件中的字段及类型信息:
l .tvd文件用于映射被存储了的域中的词条的信息(.tvf文件中)
对于每个域,.tvf文件中包含该域中词条的信息(名字以及频率等)。
.tvf文件中的字段及类型信息:
l Field (.tvf) --> TVFVersion
l TVFVersion --> Int
l NumTerms --> VInt
l NumDistinct --> VInt -- Future Use
l TermFreqs -->
l TermText -->
l PrefixLength --> VInt
l Suffix --> String
l TermFreq --> VInt
对于词条字符串的表示方法与前面.tis文件的前缀表示方法相同。
15. Per-segment文件之Deleted Document信息
.del文件是可选的,当一个段中包含被标记为删除的文件时才存在。
.del文件的字段及类型信息:
l Deletions (.del) --> ByteCount,BitCount,Bits
l ByteSize,BitCount --> Uint32
l Bits -->
.del文件的描述信息:
l ByteCount指示集合里的字节数,通常为(SegSize/8)+1,每个文档对应一个位。
l BitCount指示当前集合里被设置了的位数。