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
表示字符串的长度;
Ø
UInt32
,
4
个字节的整数;
Ø
UInt64(Long),8个字节的整数。
详细说明见下表:
Index File Composing
NLucene的索引文件存在一个索引目录中。文件共有10种
:*.f(n), *.fdt, *.fdx, *.fnm, *.frq, *.prx, *.tii, *.tis, deletable, seqments。下面分别描述:
Ø
segments
文件,用来表示索引文件的名字和
Document
的个数。在
SegmentInfos
描述,参见
write()
文件头中的第
1
个
4Byte
是
SegmentName
,在
NLucene
中,
SegmentName
是一个
16
进制的数字,是上面的如
*.fnm
中的
*
部分,每新增加一个
Document
,
SegmentName
会加
1
,所以此部分的值会比实际的
SegmentName
大
1
。文件头中的第
2
个
4Byte
是索引文件的个数,
Lucene
支持在一个目录中存放多个索引文件。文件体中
是一个可重复的部分,重复的次数由文件头中的第
2
部分的大小决定。可重复的部分包括
2
个部分:
SegmentName
和该索引文件中包含的
Document
个数。(从这里可以看出,在
Lucene
中,单个索引文件最多可以包含
2
的
32
方个文件(
4
个
byte
);
Ø
*.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
:该
Field
在
Document
的顺序,是第几个
Field
Flag
:该
Field
是否是一个
Token
(
field.isToken()==true
)
Value
:该
Field
的值
Ø
*.fdx
文件,用于存放每个
Document
在
fdt
文件中的偏移。
每个
Document
中记录的是一个
Long
型的整数,代表
*.fdt
文件中每个
Document
的偏移(起点
-1
)
Ø
*.tis
文件,用于存放切分过的
Field
中的值。(参看
2
,
fnm
文件)文件格式参看
TermInfosWriter
文件中的
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
中的
next()
函数,这是一个读单个
term
的函数。
Ø
deletable
文件,用来存放被删除的文件名。文件格式参看
IndexWriter
中的
readDeleteableFiles()
函数)文件体中
是一个
4byte
的整数,代表被删除的文件个数文件体中是一组被删除的文件名。还有
*.f(n)
是存放
Norm
的文件
,*.tii
是与
*.tis
相对的,
*.frq
(存放词频的文件),
*.prx
(存放词频的位置的文件,与
*.frq
文件联合使用。
还没有评论,来说两句吧...