欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

lucene索引过程详解

程序员文章站 2022-05-16 09:09:31
...

一、索引是LUCENE最重要的一个过程,通过IndexWriter的addDocument接口,可以将构建的Document加入索引。

二、IndexWriter的addDocument方法首先创建一个DocumentWriter对象,接着为Segment命名,然后调用DocumentWriter的addDocument()方法向索引中增加文档,最后将Segment的信息保存,如果有多个segment则判断是否需要合并,如果需要则合并。一个索引可能有多个segment,每个segment里有许多Document。每个segment的前缀生成方式是将segmentInfos.couter值(当前segment中总共的文档数量)先加1,再转移成36进制,然后在前面加一个下划线就成为了segment的名称。

三、DocumentWriter的addDocument方法完成实际的数据存储工作。

1)第一步,首先初始化一个FieldInfos对象,然后将当前Document传入其中,把所有Field的信息(注意不是内容)写入.fnm文件(在FieldInfos.write完成)。

(A)在写入工作之前使用FieldInfos.add方法将当前的Document加入到fieldInfos对象中。

(B)FieldInfos.write实现:

public void write(Diretory d,String name) throws IOException{

IndexOutput output=d.createOutput(name);

try{

//写入fields信息

write(output);

}finally{

//关闭输出流

output.close();

}

}

public void write(IndexOutput output) throws IOException{

//先写入Fields的数量

output.writerVInt(size());

//对所有Fields进行循环

for (int i=0;i<size();i++) {

FieldInfo fi=fieldInfo(i);

byte bits=Ox0;

if (fi.isIndexed) bits|=IS_INDEXED;

if (fi.storeTermVector) bits|=STORE_TERMVECTOR;

if (fi.storePositionWithTermVector) bits|=STORE_POSITIONS_WITH_TERMVECTOR;

if (fi.storeOffsetWithTermVector) bits|=STORE_OFFSET_WITH_TERMVECTOR;

if (fi.omitNorms) bits|=OMIT_NORMS;

output.writeString(fi.name);

output.writeByte(bits);

}

}

2)第二步,使用fieldWriter.addDocument方法将Document中的各个Field信息写入.fdt文件和.fdx文件。

(A)首先,向.fdx写入当前Document的位置信息

(B)接着,将需要存储的field的数量写入.fdt中

(C)遍历field。

a)如果当前field需要存储,向.fdt中写入field的编号

b)使用位运算来表示当前field的各种属性。向.fdt中写入当前field属性

c)如果field需要压缩,则进行压缩,将压缩后的field数据长度写入.fdt,之后,向.fdt中写入field的值。

d)如果不需要压缩,如果field是二进制类型,则将field数据长度写入.fdt,之后,向.fdt中写入field的值;如果不是二进制类型,直接向.fdt写入field的值

3)第三步,初始化hashtable和其它一些长度数据。

4)调用invertDocument进行文件倒排,有2个主要部分

A)对所有需要加入索引的field进行遍历。对于那些不需要分词的field,就将其整个field的数据做为一个大词条,放入postingTable(一个hashtable)中去(使用adddPostion方法加入名称、值、频率、位置,如果要求还要加上词条向量)。

B)对于需要分词的field,则调用底层分词接口进行分词,然后将每个分出来的词都放入到postingTable中去。

5)第四步,将postingtable进行转化成posting数组进行排序。使所有词条按字典顺序排列

6)第五步,将排列好的词条信息写入.tii和.tis文件,将频率和位置信息.frq和.prx文件

A)lucene索引中对词条的保存并非完整的词条本身,如"smi smith steve" 保存为"smi" "th" "teve"词条片段。

四、索引文件格式

1)segment

每个segment代表lucene的一个完整索引段。在一个索引中,会包含多个segment。每个segment都有统一的前缀,这个前缀是根据当前索引的Document的数量而确立的。一个完整的索引,只有一个segments文件,记录当前索引中所有segment的信息。

2).fnm

.fnm格式的文件中包含了Document中的所有field名称。

3).fdx和.fdt格式

.fdt用于存储具有Store.YES属性的Field的数据。而.fdx类型文件则是一个索引,用于存储Document在.fdt中的位置。

4).tii和.tis格式

.tii用于存储分词后的词条,而.tii是它的索引文件,标明了每个.tis文件中的词条的位置。

五、复合索引格式.cfs

在IndexWriter中有一个属性:useCompoundFile,默认值为True,在初始化完一个IndexWriter对象后,使用setUseCompoundFile(boolean)方法将useCompoundFile的属性值设为True

相关标签: lucene 工作