以单机搜索为例,暂不考虑分布式搜索
分析版本为: lucene_solr_branch_4x
配置文件solrconfig.xml
在solr启动的过程中加载solrconfig.xml,初始化文件中定义的信息,如处理请求的handler。
<requestHandler name="/select" class="solr.SearchHandler">
<!-- default values for query parameters can be specified, these
will be overridden by parameters in the request
-->
<lst name="defaults">
<str name="echoParams">explicit</str>
<int name="rows">10</int>
<str name="df">text</str>
</lst>
</requestHandler>
启动solr,发送请求:
http://localhost:8983/core1/select?q=id:GB18030TEST&wt=xml由core1处理查询请求,查询id=GB18030TEST 的doc,并以xml格式返回
请求分发器SolrDispatchFilter
当一个查询请求过来时,先到类SolrDispatchFilter-->doFilter(),由这个分发器中的dofilter()方法进行解析请求URL,
core = cores.getCore(corename);
根据url可以获得corename=“core1” 即使用core1进行处理查询请求,path="/select" 即请求请求对应的处理handler是"/select"。
final SolrConfig config = core.getSolrConfig();
获取core1对应的solrconfig信息。
handler = core.getRequestHandler( path );
获取"/select"对应的RequestHandler。
this.execute( req, handler, solrReq, solrRsp );
将请求请求和相关信息交由SolrDispatchFilter-->execute()处理
sreq.getContext().put( "webapp", req.getContextPath() );
sreq.getCore().execute( handler, sreq, rsp );
这里将会调用SolrCore类的
execute()方法,是solrCore留下的接口来处理请求的。
进入SolrCore类
先向SolrQueryResponse中添加一些响应首部的一些信息,
handler.handleRequest(req,rsp);
将处理权交由RequestHandlerBase-->handleRequest()进一步处理。
进入RequestHandlerBase类
handleRequestBody( req, rsp );
将处理权交由
RequestHandlerBase子类:SearchHandler-->handleRequestBody()进一步处理
进入 SearchHandler类
for( SearchComponent c : components ) {
c.prepare(rb);
}
遍历solrconfig中配置的searchhandler的各个组件,调用各个组件的prepare()方法
// Process
for( SearchComponent c : components ) {
c.process(rb);
}
调用各个组件的process()方法,运行组件,将获取的信息添加到ResponseBuilder对象中。该次查询有QueryComponent、FacetComponent、MoreLikeThisComponent、HighlightComponent、
StatsComponent、DebugComponent这几个组件参与。
以查询组件为例
QueryComponent-->process(ResponseBuilder rb)
// normal search result
searcher.search(result,cmd);
rb.setResult( result );
将查询结果添加到
ResponseBuilder对象中,然后返回,具体查询细节,可以跟踪调试下,这里不再陈述。
结尾
以上执行完以后,返回到SolrDispatchFilter-->doFilter()执行以下程序:
QueryResponseWriter responseWriter = core.getQueryResponseWriter(solrReq);
writeResponse(solrRsp, response, responseWriter, solrReq, reqMethod);
将返回结果以xml的形式返回
finally {
if( solrReq != null ) {
solrReq.close();
}
if (core != null) {
core.close();
}
SolrRequestInfo.clearRequestInfo();
}
结束操作,清除solrreq和core对象实例,剩下交由 jetty来善后了。
网上有篇NB的分析文章:http://blog.csdn.net/duck_genuine/article/details/6962624讲得相当不错。