elasticsearch源碼分析之search模塊(client端)


elasticsearch源碼分析之search模塊(client端) 

注意,我這里所說的都是通過rest api來做的搜索,所以對於接收到請求的節點,我姑且將之稱之為client端,其主要的功能我們可以簡單地概括為將的數據請求發送到node,然后在對返回的結果做處理並返回給調用方,話雖如此,但是過程並非那么簡單。

請求初始化

1、api的注冊,上一篇已經提到了,所以的api都是通過Guice框架注冊進來的,在注冊的時候會在controller上將不同的url綁定到不同的handler中:

controller.registerHandler(GET, "/_search", this); controller.registerHandler(POST, "/_search", this); controller.registerHandler(GET, "/{index}/_search", this); controller.registerHandler(POST, "/{index}/_search", this); controller.registerHandler(GET, "/{index}/{type}/_search", this); controller.registerHandler(POST, "/{index}/{type}/_search", this); controller.registerHandler(GET, "/_search/template", this); controller.registerHandler(POST, "/_search/template", this); controller.registerHandler(GET, "/{index}/_search/template", this); controller.registerHandler(POST, "/{index}/_search/template", this); controller.registerHandler(GET, "/{index}/{type}/_search/template", this); controller.registerHandler(POST, "/{index}/{type}/_search/template", this); 

上述的url都屬於search的范疇,

2、當接收到請求后,client端會parseSearchRequest,對於請求進行解析,解析結果用一個SearchRequest來表示,我們來看看包含哪些內容:

其他的不多說,特別地,對於source的解析是核心所在,由parseSearchSource來完成,返回一個SearchSourceBuilder,其主要包含:

private QuerySourceBuilder querySourceBuilder; private QueryBuilder postQueryBuilder; private BytesReference filterBinary;

其實就相當於分解動作了,所以的search不外乎都是由這些要素組成,主要包括query、filter、aggs等等。

請求的執行

1、接下來,client會將send request:client.search(searchRequest, new RestStatusToXContentListener<SearchResponse>(channel));,其中channel用於處理回調,返回的類型為SearchResponse

2、對應action的構建:

public void search(final SearchRequest request, final ActionListener<SearchResponse> listener) { execute(SearchAction.INSTANCE, request, listener); } 

其中SearchAction.INSTANCE就是一個search action的實例。listener監聽回調。

3、用proxy來發送請求到server,上面的proxy其實是一個TransportProxyClient的實例,在Transport模塊中其實已經說過了,請求都是由proxy的發送的:

protected <Request extends ActionRequest, Response extends ActionResponse, RequestBuilder extends ActionRequestBuilder<Request, Response, RequestBuilder>> void doExecute(Action<Request, Response, RequestBuilder> action, Request request, ActionListener<Response> listener) { proxy.execute(action, request, listener); } 

底層還是調用的TransportService的sendRequest,而發送到的node由DiscoveryNode node = nodes.get((index) % nodes.size());來決定,可以理解為輪訓選取一個node(其實這里看到的和我之前的理解是有些大不一樣了,我一直以為client端是直接發送給不同的shard所在的node上,再把結果合並起來的,難道之前理解是錯的???)。

獲取到從node返回的結果之后。由listener通過channel返回給調用方。

總結

client端的工作大體就是這么些了,下一遍再來說說在server端的工作了,server端的會比較麻煩一點,查詢還會分query、fetch上面的,下一篇再見咯。

 

轉載請注明出處:http://www.opscoder.info/es_search_client.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM