lucene理论—存储(转)

三:存储:

1:主要是对几个文件的结构的功能进行讲叙,了解数据结构

2:翻译官房文档:只讲file formats,文件存储格式

关于Query Parser Syntax这个就去自己看了,或者直接看程序了,file formats里面其实原理已经包含了Query Parser Syntax

3:Lucene文件格式官方文档翻译

http://lucene.apache.org/java/docs/fileformats.html

第一:文件索引简介:

 

         这个文档详细说明了2.1版本的lucene的文件格式索引。如果你使用的lucene版本不是这个版本,请查阅属于你的版本的docsfileforma.html文档。就是你下载包里的那个版本。         Apache lucenejava写成,然而几个别的程序语言写的在这个连接找到http://wiki.apache.org/jakarta-lucene/LuceneImplementations。如果这些版本和Apache lucene保持兼容,那么需要制定一个索引格式的明确定义。这个文档就提供了一个Apache Lucene 2.1的文件格式的完整的定义。         由于Lucene在发展,这个文档也不断在发展。不同语言的实现也尽量服从这个文档的文件格式定义,尤其是这个文档随着版本的更新而更新。         本文档提供了兼容性注释,描述了和以前文件格式版本的变化 

第二:定义:

 

         A:在Lucene中最重要的概念就是:索引(index)、文档(document)、字段(或叫域)(field)、不可再分的词(或叫项)(term)。         一个索引包含很多序列文档。                   1:文档(document)是一组序列字段,也就是说由几个字段组成;                   2:字段(field)是一些列项;                   3:词(term)是分词后的最小单元。         B:倒排索引                   关于分词的索引存储从统计学讲,是为了更有效的搜索。Lucene的索引就是有名的倒排索引。这是因为他就是把文档中分的词展现为序列表形式,他在文档序列项中就是一个很自然的倒排关系。         C:域的类型:                   Luncene中,域可能仅被存储,按索引先后没有倒排、逐字不分词的存储。被倒排的字段才被叫作做索引。所以一个字段可能即存储有索引                   域的内容可能通过Tokenized(空格类似的含义)进行分词索引,叫分词索引。但是有时也只对某一种字段逐字索引,叫只索引不分词         D:段                   Lucene的索引是由多个子索引组成的,或者叫段。每个段是一个独立的索引,而且能够独立搜索。索引的过程是这样:                   1:为了索引新文档,添加新段;                   2:合并已经存在的索引。                   搜索时可以同时搜索包括多个小模块或者多个索引,每个索引模块由几个段组织。         E:文档号:                   Lucene内部涉及到整形文档号。第一个索引的文档号添加从0开始,并且之后添加索引的文档号逐渐变大                   注意:文档号可能会变,所以对于Lucene功能之外存储和使用这些号就要特别小心。比如有些功能你可能设计成把docid存储了,以后拿出来用,取对应的内容。可能变得原因有,比如重做索引。 

下面详细说明,可能引起变化的情况:                   1:存储在每个索引段中的文档号必须唯一,并且必须在这些号变大前进行修改。标准技术是为每个段分配一个区间值。每个段就只使用这个区间值。每个段中的文档号从自己的区间开始值不断变大。当文档号很大时,增加的段里面的文档号从上一个结束号开始。比如:有两个2含有5个文档的段,当他们合并时,第一个段比如从文档号0开始,第二个段就从文档号5开始。下一个相邻的第三个段就要从第二个段的文档号8开始扩展。                   2:当有的文档被删除后,也就是在连续的文档号中缺了一些。在索引过程中会通过合并删除这些文档号。当段被合并时就会删除一些文档号。重新合并段就没有了空隙文档号。(重新合并才能真正删除 

第三:概况:

                  每个索引块维护下面事务:                   A:域的名称。包含在索引中使用的字段名称;                   B:存储域的值。这个包含:由于每个文档都有一系列的域,这些域的属性值被使用需要存储,如:题目,连接等就象访问的数据库。当搜索时会在相应的存储的域中会返回被命中的存储,这是文档号对应的关键字。                   C:词典。一个词典包含所有文档中的每个域进行索引分词后的词元。字典也包含了一个所有文档都包含这个词的数目;而且还指向文档的词频文件和词的前后数据。(不同与我们平时说的词典,他是lucene中倒排索引的辞典                   D:词频值。在词典中的每个词;所有文档中这个词出现的次数;并且在某一个文档中词出现的频率。                   E:词邻近的数据。词出现的位置。每个词在文档中存在这个词的位置。                   F:通常的因素(可能就是相关度)。每个文档中的每个域值多次被命中计数高的存储。                   G:词元向量。在每个文档的字段中,词元向量被存储,词元向量由词元文本和词频组成。                   H:删除文档。一个可选择的文件,表示被删除文档的标记的文件。         每个细节都会在下面章节中讲到。         第四:索引文件命名规则: 

         属于一个小索引的所有文件都有同名不同扩展名的文件名。         一般的,在索引中所有的段都存储在一个目录下,这样的要求不是必须的。        

第五:支持类型:

 

         A:字节:                   就是我们说的字节,8位的一个字节。                   支持通常的8位一个字节类型,文件被作为字节序列访问。其他数据类型由字节序列表示,因此文件格式是独立的字节序列。         B32位无符号整型:                   32位无符号整型,四个字节,存储是从高位顺序写。                   如:
         C64位无符号整型:                   64位无符号整型,八个字节,存储是从高位字节顺序写。                   如:UInt64 –> <Byte>8         D:可变长度整型:                   一个可变长格式的整型定义为:最高为存值,然后从底位顺序延伸存储的整型值。字节的最高位表明还剩多少字节,每字节的低七位表明整数的值。如:0127存储在一个单独的字节,12816383存储在第二字节,等等。                   这提供了有效的压缩编码,认为。         E:字符(Chars):                   Lucene使用的是无符号序列字符是借助javaUTF8编码。         F:字符串:                   Lucene使用的字符串类型是借助上面提到的VintChars组成的类型表示,VInt表示长度,Chars表示数据。如:                   String –> VInt, Chars 

第六:每个索引文件:

 

         在这一节里,每个索引包含的所有文件。         A:段文件,我翻译为段信息文件                   段信息文件存储着每个子段文件的信息。一个独立目录下的索引只能有一个单独的段信息文件,称为段信息文件。主要包含一系列段名和每个段的大小。如:                   Segments –> Format, Version, NameCounter, SegCount, <SegName, SegSize>^SegCount                   Version –> UInt64                   SegName –> String                    NameCounter通常被使用在新增段的命名。这个在每次打开时找到最大的。                   SegName是段的名字,并且被组成段索引的所有文件名的前缀名。                   SegSize是在某个子索引中的所有文档的数目。         B:锁文件                   有的文件被用来示意别的进程正在处理索引。注意这些文件没有存储在自己的索引目录下,而是在系统的临时目录,这正显示出Java系统特性“java.io.tmpdir”。                   1:当一个进程重写段信息文件并且删除无用的索引段中的一些文件,或者读段信息文件并且打开段信息文件时,出现文件名为“commit.lock“的文件存在。当要一个进程正在处理的读段信息文件而另一个进程又要删除文件锁文件禁止这样操作,管理保证所有信息不被破坏。                   2:当进程正在处理添加索引或者删除索引中的一些文件时,文件名为“write.lock“的文件存在。这个锁文件阻止别的进程在这个一时刻试图修改这个索引。         C:删除文件                   文件名为“deletable”的文件包括在索引中不常被使用的文件名,但是没有物理删除。在Win32系统中被使用,这样的文件仍然被打开,但是可能没被删除。在别的平台上这样的文件内容置空。                   Deletable –> DeletableCount, <DelableName>^DeletableCount                   DeletableCount –> UInt32                   DeletableName –> String          D:组合文件                   Lucene1.4之后默认使用组合文件格式。这是个简单的容器文件,组成的每个文件下一节详细描述:                   Compound (.cfs) –> FileCount, <DataOffset, FileName>^FileCount,FileData^FileCount                   FileCount –> VInt                   DataOffset –> Long                   FileName –> String                   FileData –> raw file data 

第七:每个段文件:

         每个段包含很多的文件,并且用带后缀来定义,其实用后缀来区分,也故名思意。

         A:域

拥有3个文件来表示,*Fnm*fdx*fdx             1:域信息文件:                   所有域的名字被存储在带后缀为*.fnm的域信息文件中。如:                                               FieldsCount表示多少个域                            FieldName表示域名                            FieldBits表示此域是否索引或者存储等信息                            1:底位是1表示被索引的域,0表示没有被索引的域。                            2:倒数第二底位是1表示带有词元向量的域被存储,并且0表示为不分词的域。                            Lucene1.9版本之后:                            3:如果底3位存为(0×04),词元位被存用词元向量。                            4:如果底4位存为(0×08),词元偏移向量被存用词元向量。                            5:如果底5位存为(0×10),缺省忽略索引字段。                   在*.fnm中顺序存域编号,比如在这个文件中的第一个域为0,第二个为1等等。注意,字段号和文档号没有关系。                                域的存储                   用两个文件来存储域:                   2:域索引文件,命名为*.fdx后缀的文件。这个文件包含了指向每个文档中域的数据位置,如下面:                   FieldIndex (.fdx) –> <FieldValuesPosition>SegSize                            FieldValuesPosition表示每个文档的域的位置                   说明了一个文档的域在段中的位置,Segsize说明了那个段中。                   这个被用来查找一个文档中很多域中的一个域的文本数据。因为它包含数据的偏移量并且可能容易随机被访问。某个文档的第n个域的数据的位置在这个文件中为n*8Uint64类型)。                   3:域数据文件,命名为*.fdt后缀的文件。这个文件包含每个文档中的一些域被存储,如下面:                   FieldCount –> VInt                   FieldNum –> VInt                   Lucene1.4版本之前                   Bits –> Byte                   Value –> String                   FieldCount表示为域的个数                   FieldNum表示为第几个域                   Bits表示此域如何存储                   Value域的值,应该是正排文件的意思                   一个字节的最底位仅被使用。它是1表示一个‘tokenized’域,并且0表示没有‘tokenized’域。                   Lucene1.9版本之后                   Bits –> Byte                            底位是1表示‘tokenized’域;                            倒数第二位是1表示包含二进制数据的域;                            倒数第三位是1表示一个压缩处理的域(如果可以压缩的话,使用ZLIB库);                   Value –> String | BinaryValue (依赖在这个位是1还是0决定SB)                   BinaryValue –> ValueSize, <Byte>^ValueSize                   ValueSize –> VInt

         B:词典

                   词典由两个文件组成:*.tis;*.tii                   1:词信息文件,后缀*.tis的文件                   TermInfoFile (.tis)–> TIVersion, TermCount,IndexInterval,SkipInterval,TermInfos                   TIVersion –> UInt32                   TermCount –> UInt64                   IndexInterval –> UInt32                   SkipInterval –> UInt32                   TermInfos –> <TermInfo>^TermCount                   TermInfo –> <Term, DocFreq, FreqDelta, ProxDelta, SkipDelta>                   Term –> <PrefixLength, Suffix, FieldNum>                   Suffix –> String                   PrefixLength, DocFreq, FreqDelta, ProxDelta, SkipDelta –> VInt                    TermCount表示词个数,没做索引,它都可能会变,效率:)。                   TermInfos表示指向词元向量<TermInfo>TermCount                   <TermInfo>TermCount 表示TermCountTermInfo                   TermInfo表示指向词元向量<Term, DocFreq, FreqDelta, ProxDelta, SkipDelta>                   DocFreq表示这个词对应的文档个数。                   FreqDelta表示FreqDelta determines the position of this term’s TermFreqs within the .frq file. In particular, it is the difference between the position of this term’s data in that file and the position of the previous term’s data (or zero, for the first term in the file)                            *这个文件存储词。词元按这个词属于的域顺序存,并且词元文本按字典顺序存。                   TIVersion是这个文件的格式版本,在1.4版本Lucene里,这个文件格式版本命名为-2                   词元文本前缀被共享。PrefixLength是一个含开头字母相同数的数字,从前一个词元的开始字母到下一个词元开始相同字母的长度。例如如果词元文本前一个词元是“bone”并且下一个是“boy”,PrefixLength2Suffix是”y“。                   FieldNumber指向词元的域,这个域的名字被存储在后缀为*.fdt的文件中。                   DocFreq是一个包含一个词的所有的文档的数目。                   FreqDelta指向*.frq(词频文件)文件中这个词元的TermFreqs的位置。在特殊情况下,它是在文件词元数据位置和在前缀词元数据位置不同(或0,文件中的第一个词元)。                   ProxDelta指向*.prx(位置信息文件)文件中这个词元的TermPositions位置。特别是,它是在文件词元数据位置和在前缀词元数据位置不同(或0,或文件中的第一个词元)。                   SkipDelta指向*.frq(词频文件)文件中这个词元的SkipData的位置。特别是,它是在TermFreqs之后,从SkipData开始的一个数据。换句话说,它是长TermFreq数据。                   2:词元索引信息文件,后缀名*.tii,起到缓存作用。                   这个包含每个加入*.tis文件的索引间隔,顺延添加在.tis文件中。这样设计可以被读进内存并且提供随机访问*.tis文件。                   这个文件结构对*.tis文件来说非常小,仅每个记录的项被添加。                   TermInfoIndex (.tii)–> TIVersion,IndexTermCount,IndexInterval,SkipInterval,TermIndices                   TIVersion –> UInt32                   IndexTermCount –> UInt64                   IndexInterval –> UInt32                   SkipInterval –> UInt32                  TermIndices –> <TermInfo, IndexDelta>IndexTermCount                   IndexDelta –> VLong                    TermIndices指向<TermInfo, IndexDelta>IndexTermCount                   IndexTermCount表示索引词数                   TermInfo*.tis中的TermInfo一样                   IndexDelta表示指向在*.tis文件中的这个词元的TermInfo位置。特别是,在进入词元文件位置和前缀词元位置不同。                   TODO:文档概貌信息。

         C:词频

                   .frq文件中包含每个词在文档中出现的频率。                   FreqFile (.frq) –> <TermFreqs, SkipData>TermCount ====>  表示词频文件是个指向向量行,有termcount                   TermFreqs –> <TermFreq>DocFreq                   ====>  表示指向向量行有docfreq(包含term的文档数)行,每行是TermFreq信息,TermFreq表示按增序排序了的文档号                   TermFreq –> DocDelta, Freq?                   SkipData –> <SkipDatum>DocFreq/SkipInterval                   SkipDatum –> DocSkip,FreqSkip,ProxSkip                   DocDelta,Freq,DocSkip,FreqSkip,ProxSkip –> VInt                    TermFreqs按照词元排序(由.tis文件提供词元)。                   TermFreq影响文档号的排序标准。                   DocDelta决定文档号和词频。特别是,DocDelta2是当前文档号和先前文档号不同。当DocDelta为奇数时,词频是一,当DocDelta为偶数时,词频被看作Vint读。                   例如,TermFreqs表示一个词元在文档7发生1次,11发生3次,它使用VInts序列表示为:15223                   DocSkip记录着文档号,在序列中每个文档号被表示为不同的前缀值。FreqSkipProxSkip分别记录词频文件SkipIntervalProxFile中的位置。文件位置与词频和序列前缀词位置有关系。                   例如:如果DocFreq=35SkipInterval=16,然而有两个SkipData加入,在词频文件中包含第15和第31的文档号。第一个FreqSkip词频名由词频字节16开始,第二个词频从字节32开始。第一个ProxSkip词频名由词频字节16开始,第二个词频从字节32开始。

         D:位置

                   .prx文件中包含每个词在文档中的位置。                   ProxFile (.prx) –> <TermPositions>TermCount ===>         TermPositions表示顺序的term                   TermPositions –> <Positions>DocFreq    ====> Positions也是顺序递增的文档号                   Positions –> <PositionDelta>Freq                   PositionDelta –> VInt                    词的位置有词元排序(由.tis文件提供词元)。位置由文档号增加排序(文档号由.frq文件提供)。                   PositionDelta在当前位置和相邻前面位置不同。                   例如:TermPositions在一个文档的第4处出现,并且第5和第9个词元相减按下面VInts序列存:454

         E:通常因素(相关度?)

                   在每个文档中有一个字节索引的普通的文件。通过对每个字节编码,对每个文档进行命中09的得分:                   Norms (.f[0-9]*) –> <Byte>SegSize                   每个字节编码成实数,02位包含3作为底数,38位包含5位做指数。                   IEEE有一个简单的实数转换,见下面:                            1:如果数为0,实数就为0                            2:否则设置标记位为实数0                            3:添加48为指数并且使用这个实数;                            4:映射高3位底数                            5:设置底21位为实数0

         F:词元偏移量:

                   1:索引文档或.tvx文件                   这个文件包含指向在.tvd文件文档数据中的指针。                   DocumentIndex (.tvx) –> TVXVersion<DocumentPosition>NumDocs                   TVXVersion –> Int                   DocumentPosition –> UInt64                   NumDocs表示所有的文档号                   DocumentPosition表示指向*.tvd中的位置                   这个被用来查找在.tvd文件中的文档位置。                   2:文档或.tvd文件                   这个包含每个文档的字段号、词偏移量信息指向的字段列表和在.tvf中的字段信息指针。                    Document (.tvd) –> TVDVersion<NumFields, FieldNums, FieldPositions,>NumDocs                   TVDVersion –> Int                   NumFields –> VInt                   FieldNums –> <FieldNumDelta>NumFields                   FieldNumDelta –> VInt                   FieldPositions –> <FieldPosition>NumFields                   FieldPosition –> VLong                   NumFields表示多少个域                   FieldNums表示第几个域                   FieldPositions所有域的位置,指向每个域位置<FieldPosition>NumFields                   .tvd文件用来映射每个词元偏移量字段并且可以在.tvf文件中找到字段信息。                   3:字段或.tvf文件                   这个文件包含每个字段,字段分词后词元偏移量的存储,词元列表和次频。                   Field (.tvf) –> TVFVersion<NumTerms, NumDistinct, TermFreqs>NumFields         =====>     表示numfields个向量行,每行内容是NumTerms, NumDistinct, TermFreqs                   TVFVersion –> Int                   NumTerms –> VInt ======>            表示numterms个向量行,每行内容是TermText, TermFreq(词个数)                   NumDistinct –> VInt — Future Use                   TermFreqs –> <TermText, TermFreq>NumTerms                   TermText –> <PrefixLength, Suffix>   =====>                表示前面词和此词相同的长度和此词与前面不同的部分,之前的提到的字符压缩技术。                   PrefixLength –> VInt                   Suffix –> String                   TermFreq –> VInt                   词元文本前缀被共享。前缀长度是一个以字母开头的数字,从开始词元到词元结束的文本。然而如果词元文本象bone”和“boy”,前缀长度是2,后缀是”y“。

         G:删除文档

                   .del文件是可选的,并且在要删除块时才存在。                   Deletions (.del) –> ByteCount,BitCount,Bits                   ByteSize,BitCount –> Uint32                   Bits –> <Byte>ByteCount                    字节数显示一个多少字节的数,它的形式是SegSize/8)+1                   位数显示当前使用位的数                   位包含被索引文档的一个位。当一个文档数被设置为符合这个位时,这个文档添加了删除标记。从这个位说明一些信息。然而,如果位包含两个字节,0×000×02,那么文档号9标记为删除。 

第八:限制:

 

         有的系统限制文件格式分词和文档号的最大数不能超过32为数量级,或者相当于40亿以内。今天不是问题,但是分词多了后,可能就会有问题。然而使用UInt64位机代替还好些,或者更好的是,使用VInt类型值就没有界限了。

posted on 2008-03-05 12:03  yurow  阅读(711)  评论(0编辑  收藏  举报

导航