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重寫)

相關文章
相關標籤/搜索