浅谈lucene的正向文档

来源:互联网 发布:全国公民姓名数据库 编辑:程序博客网 时间:2024/05/01 02:13

由两个文件组成正向文档信息

1.      正向文档指针(.fdx文件)

2.      正向文档内容(.fdt文件)

 

正向文档的索引过程

l  涉及两个类

1.      FieldInfos *fieldInfos;(字段信息:例如字段名,字段属性等)

2.      FieldsWriter *fieldsWriter;(正向文档读写器)

 

l  索引过程分两部分

1.      构建部分

2.      合并部分

 

 

一、索引构建过程

//当添加文档时,调用以下addDocument(注意:每次添加文档都重复生成DocumentWriter对象,颇为浪费)函数,涉及到正向文档的主要有两块

void DocumentWriter::addDocument(const char* segment, Document* doc)

{

…………………..

// 其他过程暂时略过

 

1.      字段信息

// 遍历文档,添加字段信息

// 注意,如果每次构建的文档结构一样,那么此过程便一再重复了

       fieldInfos = _CLNEW FieldInfos();

       fieldInfos->add(doc);

      

       const char* buf = Misc::segmentname(segment, ".fnm");

       fieldInfos->write(directory, buf);

       ………….

2.      正向文档内容

       // write field values

       //FieldsWriter fieldsWriter(directory, segment, fieldInfos);

 

   // 写入字段内容

       //try

       //{

              // add by lxp

              //fieldsWriter.addDocument(doc);

       //} _CLFINALLY( fieldsWriter.close() );

 

……..

}

 

fieldInfos->add(doc);此过程功能是

1.      统计字段的属性(例如是否存储/索引/分词)

2.      建立一个映射表:字符串和数值;一一对应。可由数值查知字段名,可由字段名得知字段数值

 

 

fieldsWriter.addDocument(doc);此过程功能是

1.      遍历所有需要存储的字段,将索引信息写入磁盘(缓存)

2.      先写入正向文档的偏移值(.fdx)

3.      写入需要存储的字段个数(fieldsStream->writeVInt(storedCount);)

4.      重复以下过程

l  写入一个uint_8的该字段属性值(fieldsStream->writeByte(bits);)

l  写入字段内容(可选多种方式写入:例如是否压缩,是否二进制流)

 

 

二、合并过程

索引合并时调用int32_t SegmentMerger::mergeFields()过程合并字段内容

{

              for (uint32_t i = 0; i < readers.size(); i++) {

                     //get the i-th reader

                     reader = readers[i];

 

 

//通过计算fdt文件大小得知此段内的文档数

// (int32_t)indexStream->length()/8;

int32_t maxDoc = reader->maxDoc();

 

////Iterate through all the documents managed by the current reader

                     //for (int32_t j = 0; j < maxDoc; j++)

                     //{

                     //     //Check if the j-th document has been deleted, if so skip it

                     //     if (!reader->isDeleted(j))

                     //     {

                     //            //Get the document

                     //            if ( reader->document(j, &doc) ) //取出正向文档

                     //            {

   //                                 //Add the document to the new FieldsWriter

   //                                 fieldsWriter->addDocument( &doc );//重新写入

   //                                 docCount++;

   //                                 //doc is cleard for re-use

   //                                 doc.clear();

   //                          }

                     //     }

                     //}

              }

}

 

 

三、优化过程

IndexWriter控制正向文档的读写

1.      字段信息一次统计(因文档结构一样),由IndexWriter控制下的IndexWriter::fieldInfos

2.      正向文档一直末尾添加,不重读入,不重写入

为此

l  索引时将正向文档的读写交给IndexWriter控制下的读写器

                     IndexWriter:: fieldsWriter写入,每次追尾

l  合并过程不执行mergeFields()->//mergeFields();

l  合并过程中需要的字段信息由始至终使用IndexWriter::fieldInfos

l  合并过程中需要的文档数统计由SegmentInfo* si取得

原创粉丝点击