lucene源代码分析(index部分)

来源:互联网 发布:追魂call软件 编辑:程序博客网 时间:2024/05/22 12:32

         lucene的索引

          lucene对一系列的文件进行索引时,首先会将物理文件映射为Document类型的文件。Document中包含有和检索相关的field,这个过程将一些感兴趣的内容提取出来,而之后所有的检索都是基于Document的。

          lucene的索引分为两种,一种是将不同索引信息写到不同的文件中,一种是使用复合文件索引格式,该索引格式减少了索引文件的个数,但同时会有一定效率的降低。

经常使用IndexWriter来完成索引的建立,常见的代码是这样的:

          Document doc1=null;

          ..........................//make doc1 refer to a real file

        IndexWriter writer=new IndexWriter(INDEX_STORE_PATH, new StandardAnalyzer(),true);

        writer.add(doc1);

        writer.optimize();

        writer.close();

        那么这些代码实际的执行是怎样的呢?通过对源代码的分析,得到如下的UML类图

     

 

 

       IndexWriter的构造函数会在INDEX_STORE_PATH目录下根据create参数建立segment_gen文件,或是将目录下已有的索引信息读进来,确定segment的名字(通过确定generation编号).

      IndexWriter.add()方法将Document内容加到索引是通过方法buildSingleDocSegment(Document doc, Analyzer analyzer),该方法的实际操作委托给DocumentWriter完成。DocumentWriter.addDocument()负责将doc索引信息添加到Segment中去。由于索引信息是针对Field而讲的,所以实际的索引信息包含在FieldInfos对象里,将FieldInfo写到segment中使用了类FieldsWriter。

       此外,Field中的Term信息也是索引的重要内容,他们保存在IndexWriter的postingTable成员中。通过调用链DocumentWriter.addDocument()---------->invertDocument(Document),postingTable包含了Term的所有索引相关信息。将Term信息写到索引文件,又使用另一个类TermInfosWriter来辅助完成的。如果field的storeTermVector成员为true的话,那么还会使用TermVectorsWriter类保存TermVector信息。

       以上的TermInfosWriter,FieldsWriter,TermVectorWriter将索引信息写到文件中委托给IndexOutput类来完成。IndexOutput类是一个抽象类,提供了多种方便的接口函数供调用,最下面又是使用抽象函数writeBytes(byte[] b, int offset, int length)函数来完成,这确保了IndexOutput在不同的输出环境中可以有不同的行为。

      IndexWriter.optimize()方法尝试将小的segment归并到大的segment中去,使用SegmentMerger类的mergeSegments方法来完成。

     IndexWriter.close()方法中也会调用SegmentMerger.mergeSegment()方法。所以感觉上IndexWriter的optimize方法和close方法功能上有些重合。如果optimize与close方法连用可能体现不出optimize作用来。如果建立的索引比较大的话,可以在适当的时候直接调用optimize,然后再去添加新的文档,可能这时optimize()作用才体现出来。

     以上便是建立索引时各个类之间相互协做的大致关系