zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    计算机网络概述
    虚拟机网卡配置
    元类
    反射和内置方法
    面向对象的三大特性
    MYSQL中EXISTS的用法
    Guava中的常见集合操作用法
    集合操作交并补的三种Java实现
    P9 get和resize操作(Java 13)
    P8 Java 13中 HashMap的 put方法
  • 原文地址:https://www.cnblogs.com/bonelee/p/7232886.html
Copyright © 2011-2022 走看看