Lucene搜索流程(3.IndexSearcher)

不知道你们看了上一篇的关于IndexReader的粗浅介绍是否有所收获,若是感受到有不明白的地方请@我。java

好了,按照流程来,今天咱们就来讲说IndexSeacher,小二上茶~~~~~~~哈哈分布式

到了IndexSearcher这里就应该到了离咱们最近的地方了,也能够说是咱们用的最多的地方了,下面代码相信你们都不会陌生:函数

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

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

其实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就会在搜索的时候对这些目录同时并行搜索,而后将每一个目录获取的结果进行加工处理(排序,过滤...),返回给咱们的就是一份可用的数据了,这个对分布式搜索来讲意义是很大的。code

关于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重写)

相关文章
相关标签/搜索