NLucene研究系列(3)-基本机制

 

Data Flow

       NLucene内部的数据流图如下所示,共包含了4种数据流格式:分别是文本流、Token流、字节流与查询语句对象流。文本流表示了对于索引目标和交互控制的抽象,即用文本流表示了将要索引的文件,用文本流向用户输出信息;在实际的实现中,NLucene中的文本流采用了UCS-2作为编码,以达到适应多种语言文字的处理的目的。Token流是NLucene内部所使用的概念,是对传统文字中的词的概念的抽象,也是NLucene在建立索引时直接处理的最小单位。字节流则是对文件抽象的直接操作的体现,通过固定长度的字节(NLucene定义为8比特位长,后面文件格式将详细叙述)流的处理,将文件操作解脱出来,也做到了与平台文件系统的无关性。查询语句对象流则是仅仅在查询语句解析时用到的概念,它对查询语句抽象,通过类的继承结构反映查询语句的结构,将之传送到查找逻辑来进行查找的操作。

 



Index File Formats

 


NLucene中的索引信息以文件形式保存。其逻辑结构如上图所示:一个Index可以分为若干个Segment(Segment可以合并,详见后文),每个Segment由若干个Document组成,然后再进一步分成Filed, Term, 从而形成了如上的逻辑构图。为了帮助理解,我们可以用熟悉的数据库系统作个隐喻,Segment相当于Database, Document对应于Table, 而Filed就相当于Table中的Column, Term就是Row中具体的内容。NLucene采用了自定义的数据类型将这些索引文件存储到一些列的文件中。由于这种基于bit的数据存储格式,使得索引文件具有良好的跨平台性。

需要注意的是,索引结构不但能建立在文件系统(FSDirectory)中也可以建立在内存(RAMDirectory)中。

Defined Data Type

在介绍索引文件之前,先描述一下几个文件格式中常用的数据类型:

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

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

Ø         VString,由于Lucene的开发语言java中的字符串是没有像C里面一样的’\0’的结束符的,所以在文件中记录一个字符串时,在字符串前放一个VInt表示字符串的长度;

Ø         UInt324个字节的整数;

Ø         UInt64(Long),8个字节的整数。

详细说明见下表:

 



Index File Composing

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

Ø         segments文件,用来表示索引文件的名字和Document的个数。在SegmentInfos描述,参见write()文件头中的第14ByteSegmentName,在NLucene中,SegmentName是一个16进制的数字,是上面的如*.fnm中的*部分,每新增加一个DocumentSegmentName会加1,所以此部分的值会比实际的SegmentName1。文件头中的第24Byte是索引文件的个数,Lucene支持在一个目录中存放多个索引文件。文件体中 是一个可重复的部分,重复的次数由文件头中的第2部分的大小决定。可重复的部分包括2个部分:SegmentName和该索引文件中包含的Document个数。(从这里可以看出,在Lucene中,单个索引文件最多可以包含232方个文件(4byte);

Ø         *.frm文件,用来保存FieldName,注意,此文件只保存非切分部分的Field,如通过Filed.text()方法进行切分后的Field保存在*.tii, *.tis中。
具体格式如下:(在FieldInfos描述,参见write()
文件头中的FieldNum代表索引的Field的个数。文件体中描述每个Field的信息,个数与文件体中的FieldNum相同。每个Field的信息包括2个部分:FieldName,索引的Field的名字,Flag表示该Field是否是索引的(indexed)。0×00表示未索引,0×01表示索引。

Ø         *.fdt文件,用于存放Field的值,每个Document是连续存放的,每个Document内部的格式如下:(参看FieldsWriter文件的AddDocument()函数)头部中的FieldNum是该Document中选择了存储的Field的个数(field.isStroed()==true),内容体中每个Filed中包括3个部分。
Pos
:该FieldDocument的顺序,是第几个Field
Flag
:该Field是否是一个Tokenfield.isToken()==true
Value
:该Field的值

Ø         *.fdx文件,用于存放每个Documentfdt文件中的偏移。
每个Document中记录的是一个Long型的整数,代表*.fdt文件中每个Document的偏移(起点-1

Ø         *.tis文件,用于存放切分过的Field中的值。(参看2fnm文件)文件格式参看TermInfosWriter文件中的add()函数)文件头中的TermNum是一个4byteInt,代表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中的next()函数,这是一个读单个term的函数。

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

posted @ 2006-12-15 23:18  Anders.Lee  阅读(678)  评论(0编辑  收藏  举报