lucene的IndexReader的初始化过程

         在使用Lucene时,有一条建议”不要频繁去打开关闭硬盘索引”。为什么会有这条建议?这就需要在IndexReader的实例化过程中找答案。先说一个结论“IndexReader的实例化过程是一个非常耗时的过程”。由于IndexReader只是一个抽象类,在调用代码:

wKioL1PZwTvBayhhAACEyJ52NVs220.jpg

真正得到的是StandardDirectoryReader对象。首先来看一下StandardDirectoryReader的类图:

wKiom1PZwC3xMwKjAAD5nNg_GJs536.jpg

最重要的一个类就是SegmentCoreReader,它关联着整个segment中的所有文件。SegmentCoreReader是通过Codec来得到各个文件的处理对象,结构图如下:(可以在新标签页面中查看大图,会更清晰一些)

wKioL1PZwVTSEF4-AAFSGTmdRps340.jpg

初始化过程的关键的JAVA代码如下:

wKiom1PZwEWjbZK4AAE4oyTSOgw352.jpg

在SegmentInfos.FindSegmentsFile.run(commit)方法执行的过程中,会读取segments.gen文件,确定segments的最大的generation。在StandardDirectoryReader.open(Directory)方法执行的过程中,sis.read(directory,segmentFileName)在执行过程中步骤如下:

 

1、  通过segments_N的文件名得到N的最大值,即索引的最后CommitPoint。

2、  对比segments.gen文件中写入的两个generation值,得到N的最大值。

3、  从segments_N中读取到索引段的总体信息,并依次读取出所有si文件。

4、  从每个_N.si 文件中读取索引段的相关信息(操作系统信息,Lucene版本信息,当前段管理的文件信息),形成SegmentInof对象,最后汇总得到SegmentInfos对象

5、  用CRC32校验segments_N文件的正确性。

 

对于每个SegmentInfo对象,都会生成一个SegmentReader对象,即代码:

readers[i]=new SegmentReader(sis.info(i),termInfosIndexDivisor,IOContext.READ);


这段代码就是读取每个segment的总体信息,比如docCount,totalTermFreq等信息,并把segment中的相关文件关联起来。在SegmentCoreReader类的构造函数里,把索引的核心文件都打开且读取了相关信息。

 

1、  依次读取每个段的文件信息。

2、  从_N.fnm文件中读取每个Field的配置信息,得到相当段的所有FieldInfo,组成FieldInfos。

3、  打开倒排表的相关文件(doc/pos/pay)

4、  打开词典文件(tim/tip)

5、  读取索引的统计信息(docFreq,tatalTermFreq,docCount等信息)

6、  读取nvm/nvd文件,得到相关norms信息。

7、  读取fdx/fdt文件。

        

通过这些初始化过程,就完成了IndexReader的初始化。当索引的数据很大时,这个加载过程就比较耗时了。所以“不要频繁去打开关闭硬盘索引”。

 

本文出自 “每天进步一点点” 博客,请务必保留此出处http://sbp810050504.blog.51cto.com/2799422/1533198

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值