1.攔截請求,解析請求並構建相應的handler。
發送檢索請求,例如:http://localhost:8983/solr3.5/core2/select/?q=*%3A*&version=2.2&start=0&rows=10&indent=on
首先他將被SolrDispatchFilter攔截。
?
doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
|
經過對request的分析,獲知當前request是作什麼的(/select),並構造相應的handler(SearchHandler)。
2.SolrCore出面處理上層工做(具體工做交由handler處理)
將handler、SolrQueryRequest、SolrQueryResponse交由solrCore的execute方法處理
?
public void execute(SolrRequestHandler handler, SolrQueryRequest req, SolrQueryResponse rsp)
|
在該方法中主要仍是由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處理。
(這裏的設計方式有點相似於servlet,GenericSerlet實現了一些公用方法,而具體的則有其子類完成,例如HttpServlet)
3.SearchHandler具體的檢索過程
如今的檢索沒有使用shards,在跟蹤代碼的過程當中,發現如下過程是檢索的主要環節。
if(!rb.isDebug()) {
// Process
for( SearchComponent c : components ) {
<strong> c.process(rb);</strong>
}
}
|
從中可知真正的檢索須要通過多個SearchComponent,在當前的實驗環境下包括6個,以下:
4.各個SearchComponent配合工做完成檢索
咱們先重點了解QueryComponent。
得到SolrIndexSearcher,這個對象是檢索的主要執行者。
同時獲取SolrIndexSearcher.QueryCommand、SolrIndexSearcher.QueryResult,並將其做爲查詢條件和查詢結果提交給SolrIndexSearcher進行檢索。
searcher.search(result,cmd);
|
在SolrIndexSearcher中search方法以下:
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)
那麼後面5個Component就直接過了(沒有真正被執行)。
5.收尾工做
將結果封裝好,寫入相應的ResponseHeaders,關閉SolrQueryRequest、solrCore。
-----------------------------------------------------
以上是solr-searching最粗略的過程,本着先脈絡後細節的思想,之後再對各個重要環節作深刻分析。
searching主要執行方法以下:
SolrDispatchFilter(doFilter,execute)
->SolrCore(execute)
->RequestHandlerBase(handleRequest)
->SearchHandler(handleRequestBody) //有可能執行多個Component
->QueryComponent(process)
->SolrIndexSearcher(search,getDocListC)