Lucene搜索流程(3.IndexSearcher)

不知道大家看了上一篇的关于IndexReader的粗浅介绍是否有所收获,如果感觉到有不明白的地方请@我。

好了,按照流程来,今天我们就来说说IndexSeacher,小二上茶~~~~~~~哈哈

到了IndexSearcher这里就应该到了离我们最近的地方了,也可以说是我们用的最多的地方了,下面代码相信大家都不会陌生:

IndexSearcher searcher=new IndexSearcher(new IndexReader(FSDirectory.open(new File("d:/index"))));
searcher.query(.....);

这就是一个最简单的搜索步骤了,前两篇文章我们已经说了Directory和IndexReader了,这里我们就来好好看看IndexSearcher。

其实IndexSearcher也相当于一个门面模式,它把Lucene的许多搜索功能全部都整合在一起了供外部使用,相当于提供给外部使用的一个接口(但是它并非接口),有了Seacher我们就可以选择一个索引目录,然后打开进行相关的搜索操作了,什么查询、排序、过滤之类的全部都是在它里面完成的,但是它也是通过调一些其他的模块来达到这些功能的,所以我们可以看做它是一个整合功能的提供者。

我们首先来看一个完整的构造函数:

public IndexSearcher(IndexReader reader, IndexReader[] subReaders, int[] docStarts, ExecutorService executor) {
    this.reader = reader;
    this.subReaders = subReaders;//指定子IndexReader
    this.docStarts = docStarts;//当前Searcher的docId的起始值
    if (executor == null) {
      subSearchers = null;
    } else {//如果要支持并行搜索,前面我们讲过的,这里就将每个子Reader包装成一个子Searcher,让他们可以独立搜索
      subSearchers = new IndexSearcher[subReaders.length];
      for(int i=0;i<subReaders.length;i++) {
        subSearchers[i] = new IndexSearcher(subReaders[i], docStarts[i]);
      }
    }
    closeReader = false;//是否在关闭的时候同时关闭IndexReader
    this.executor = executor;
    docBase = 0;//docBase的存在是指有时候我们可以指定这个Seacher从那个docId开始
  }

还有另外一个构造函数,跟这个差不多,但是他的子Reader并不是由用户指定的,而是通过IndexReader.getSequentialSubReaders();方法来进行收集的,这个方法会返回当前IndexReader的所有子Reader,IndexSeacher会递归去获取他们的子Reader,直到这个方法返回null。

说到IndexSearcher,我们就来说说多目录索引。有时候我们查询索引的时候并不是从一个单一的目录里面去查询的(有时候我们的索引太大时我们也会分目录来存放提高索引效率),索引我们要获取的结果就并不是从一个目录里面获取了,这时候我们就可以一个类MultiIndexReader(这个貌似应该放到前一篇讲?),通过这个类我们就可以为每个目录实例化一个IndexReader然后用它将他们联合在一起组合成一个对IndexSearcher可用的IndexReader,然后IndexReader可以通过收集子Reader将这些目录分别收集起来,如果我们在初始化一个新的IndexSearcher的时候就提供一个线程池(ExecutorService),那么Lucene就会在搜索的时候对这些目录同时并行搜索,然后将每个目录获取的结果进行加工处理(排序,过滤...),返回给我们的就是一份可用的数据了,这个对分布式搜索来说意义是很大的。

关于IndexReader里面的方法我们用的最多的恐怕就是:

public TopFieldDocs search(Weight weight, Filter filter,  final int nDocs, Sort sort) throws IOException;
public void search(Weight weight, Filter filter, Collector collector) throws IOException;

这两个方法就是我们的搜索入口啦,其他的search方法或多或少就是对这两个方法的重载,这里search方法里面究竟有什么动作?或者是Seacher为我们做了些什么事情?我们是怎么从索引里面获得我们想要的数据的?这些问题我们在这里先卖个关子,等到下一篇Query文章中我会替大家介绍Lucene究竟是怎么做的,我们也会感叹Lucene的设计的精妙之处!

这一篇的篇幅比较少,希望在下一篇能够补上,其实Query能说的东西太多了,甚至每一个Query都可以用很长的篇幅来说名作用的工作原理,所以各位如果有兴趣请关注我的下一篇文章

Lucene搜索流程(4.Query重写)

转载于:https://my.oschina.net/zengjie/blog/75252

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值