【转载】 Searching过程粗略梳理
轉載自:http://www.cnblogs.com/huangfox/archive/2012/02/09/2344686.html
solr-searching過程分析(一)
——searching過程粗略梳理
?
下午看了一會solr的啟動過程,往細的看相當繁瑣。換個頭緒先看看solr的searching過程。
?
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)
創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎
總結
以上是生活随笔為你收集整理的【转载】 Searching过程粗略梳理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 修改Linux中的用户名
- 下一篇: 【转载】solr教程,值得刚接触搜索开发