轉載--solr的searching過程(1)

1.攔截請求,解析請求並構建相應的handler html

發送檢索請求,例如:http://localhost:8983/solr3.5/core2/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on 緩存

首先他將被SolrDispatchFilter攔截。 ide

? spa

doFilter(ServletRequest request, ServletResponse response, FilterChain chain) 設計

經過對request的分析,獲知當前request是作什麼的(/select),並構造相應的handlerSearchHandler)。 component

 

2.SolrCore出面處理上層工做(具體工做交由handler處理) orm

handlerSolrQueryRequestSolrQueryResponse交由solrCoreexecute方法處理 htm

? 對象

public void execute(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp) blog

在該方法中主要仍是由handler來完成的。

SolrRequestHandler是一個接口,他主要的方法就是:

?

public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp);

SolrRequestHandler的實現類的結構圖以下:

其中RequestHandlerBase爲大部分的Handler實現了部分功能,主要包括

?

public void handleRequest(SolrQueryRequest req, SolrQueryResponse rsp){

  ......

  handleRequestBody( req, rsp );

  ......

}

然而具體怎麼作就交給具體的子類去執行了!(handleRequestBody( req, rsp );

例如:這裏是作檢索,那麼就交由SearchHandler處理。

(這裏的設計方式有點相似於servletGenericSerlet實現了一些公用方法,而具體的則有其子類完成,例如HttpServlet

 

3.SearchHandler具體的檢索過程

如今的檢索沒有使用shards,在跟蹤代碼的過程當中,發現如下過程是檢索的主要環節。

?

if(!rb.isDebug()) {

        // Process

        for( SearchComponent c : components ) {

         <strong> c.process(rb);</strong>

        }

      }

從中可知真正的檢索須要通過多個SearchComponent,在當前的實驗環境下包括6個,以下:

 

4.各個SearchComponent配合工做完成檢索

咱們先重點了解QueryComponent

得到SolrIndexSearcher,這個對象是檢索的主要執行者。

同時獲取SolrIndexSearcher.QueryCommandSolrIndexSearcher.QueryResult,並將其做爲查詢條件和查詢結果提交給SolrIndexSearcher進行檢索。

?

searcher.search(result,cmd);

SolrIndexSearchersearch方法以下:

?

public QueryResult search(QueryResult qr, QueryCommand cmd) throws IOException {

    <strong>getDocListC(qr,cmd);</strong>

    return qr;

  }

getDocListC又是一個比較複雜的方法,在這裏加入的cache

若是當前檢索被緩存了(緩存也是個重點內容,後續詳細分析!),那麼直接返回結果,不然從新進行檢索,檢索的方法是:

?

private void getDocListNC(QueryResult qr,QueryCommand cmd)

在該方法中,和咱們使用lucene進行檢索十分類似,採用的具體方法是:

?

super.search(query, luceneFilter, collector);

檢索完成將結果進行封裝,放入QueryResult當中。

?

qr.setDocList(new DocSlice(0,sliceLen,ids,scores,totalHits,maxScore));

檢索完成後,將結果放入緩存中,造福後人

至此QueryComponent的工做就算完成了。

若是作簡單查詢(如:http://localhost:8983/solr3.5/core2/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on

那麼後面5Component就直接過了(沒有真正被執行)。

 

5.收尾工做

將結果封裝好,寫入相應的ResponseHeaders,關閉SolrQueryRequestsolrCore

 

-----------------------------------------------------

以上是solr-searching最粗略的過程,本着先脈絡後細節的思想,之後再對各個重要環節作深刻分析。

searching主要執行方法以下:

SolrDispatchFilterdoFilter,execute

->SolrCore(execute)

->RequestHandlerBase(handleRequest)

->SearchHandler(handleRequestBody) //有可能執行多個Component

->QueryComponent(process)

->SolrIndexSearcher(search,getDocListC)

相關文章
相關標籤/搜索