elasticsearch源码分析之search模块(server端)
elasticsearch源码分析之search模块(server端)
继续接着上一篇的来说啊,当client端将search的请求发送到某一个node之后,剩下的事情就是server端来处理了,具体包括哪些步骤呢?
过程
一、首先我们来看看接收地方其实就是在org.elasticsearch.action.search.TransportSearchAction中,收到请求之后会判断请求的index的shard是否只有一个,如果是一个的话,那么会强制将请求的type设置为QUERY_AND_FETCH,因为所以的事情在此shard上就能够做完了。所以如果设置了routing,而让请求落在了一个shard上时,搜索的效率会高很多的原因。
二、根据不同的type来确定不同的处理方式,这里补充一下,上一篇可能忘记说了,search的type一般来说分为“DFS_QUERY_THEN_FETCH、QUERY_THEN_FETCH、DFS_QUERY_AND_FETCH、QUERY_AND_FETCH”这四种,还有“SCAN、COUNT”在ES2.X里面其实已经被舍弃掉了。我们一般都是用的默认的QUERY_THEN_FETCH,上面说的一个shard的除外。所以本篇就只讨论这种情况了。
三、得到搜索的index所涉及的shard,并依次执行: 1、获取该shard所在的node并执行sendExecuteFirstPhase,实际上是向node发送了一个“QUERY”的请求:
transportService.sendRequest(node, QUERY_ACTION_NAME, request, new ActionListenerResponseHandler<QuerySearchResultProvider>(listener) {
@Override
public QuerySearchResult newInstance() {
return new QuerySearchResult();
}
});
2、node接收到"QUERY"的请求之后,执行executeQueryPhase:
首先是创建一个search的context,
SearchContext context = new DefaultSearchContext(idGenerator.incrementAndGet(), request, shardTarget, engineSearcher, indexService, indexShard, scriptService, pageCacheRecycler, bigArrays, threadPool.estimatedTimeInMillisCounter(), parseFieldMatcher, defaultSearchTimeout);
创建的具体过程就不详细说了,之后做的事情还是有parseSource、对size做判断(2.X里面最大不超过10000,可以通过配置文件配置)、……
最重要的其实是loadOrExecuteQueryPhase(request, context, queryPhase);,具体的内容是首先从cache里面执行query,如果cache里面没有找到,才会执行queryPhase:queryPhase.execute(context);;里面的处理逻辑就比较复杂了,但是最重要的是searcher.search(query, collector);,其实是调用了Lucene里面IndexSeartcher的search方法。
3、如此一来,第一阶段的query已经做完了,,接下来便是fetch的执行,入口在onFirstPhaseResult这里,在底层同样是向node发送一个“FETCH”请求咯:
4、node接收到“fetch”请求之后,执行executeFetchPhase:
fetch的核心代码如下:
。。。
大意就是轮流通过之前query结果中的docid,然后创建出InternalSearchHit的集合,并将之放在fetchResult中context.fetchResult().hits(new InternalSearchHits(hits, context.queryResult().topDocs().totalHits, context.queryResult().topDocs().getMaxScore()));,并将之返回到发送fetch的node。
四、到目前为止,该获取的数据都已经拿到了,现在要做的则是要把个node的返回结果做merge,merge的操作由SearchPhaseController来控制:
final InternalSearchResponse internalResponse = searchPhaseController.merge(sortedShardList, firstResults,
fetchResults, request);
具体的过程就不细说了,大体就是该排序的就做排序,有aggs的就做aggs……
五、通过listener将上面的结果返回:listener.onResponse(new SearchResponse(internalResponse, scrollId, expectedSuccessfulOps, successfulOps.get(), buildTookInMillis(), buildShardFailures()));给发出接收search请求的node,也就是上一篇说道的client。
总结
这样知道了,为什么返回的结果长那么个鬼样子了。整个过程的话算是走马观花地走了一遍了,其实里面还有很多detail的东西没用讲到,看一张图就知道了:

包括他们分别的具体实现什么的,所以一个查询牵扯到的东西实在太多,等有时间再去深究,可都是财富。
elasticsearch源码分析之search模块(server端)的更多相关文章
- elasticsearch源码分析之search模块(client端)
elasticsearch源码分析之search模块(client端) 注意,我这里所说的都是通过rest api来做的搜索,所以对于接收到请求的节点,我姑且将之称之为client端,其主要的功能我们 ...
- Elasticsearch源码分析 - 源码构建
原文地址:https://mp.weixin.qq.com/s?__biz=MzU2Njg5Nzk0NQ==&mid=2247483694&idx=1&sn=bd03afe5a ...
- ADB 源码分析(一) ——ADB模块简述【转】
ADB源码分析(一)——ADB模块简述 1.Adb 源码路径(system/core/adb). 2.要想很快的了解一个模块的基本情况,最直接的就是查看该模块的Android.mk文件,下面就来看看a ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- Elasticsearch源码分析—线程池(十一) ——就是从队列里处理请求
Elasticsearch源码分析—线程池(十一) 转自:https://www.felayman.com/articles/2017/11/10/1510291570687.html 线程池 每个节 ...
- 【转】Spark源码分析之-deploy模块
原文地址:http://jerryshao.me/architecture/2013/04/30/Spark%E6%BA%90%E7%A0%81%E5%88%86%E6%9E%90%E4%B9%8B- ...
- (一) Mybatis源码分析-解析器模块
Mybatis源码分析-解析器模块 原创-转载请说明出处 1. 解析器模块的作用 对XPath进行封装,为mybatis-config.xml配置文件以及映射文件提供支持 为处理动态 SQL 语句中的 ...
- Spark源码分析之-Storage模块
原文链接:http://jerryshao.me/architecture/2013/10/08/spark-storage-module-analysis/ Background 前段时间琐事颇多, ...
- DRF框架(一)——restful接口规范、基于规范下使用原生django接口查询和增加、原生Django CBV请求生命周期源码分析、drf请求生命周期源码分析、请求模块request、渲染模块render
DRF框架 全称:django-rest framework 知识点 1.接口:什么是接口.restful接口规范 2.CBV生命周期源码 - 基于restful规范下的CBV接口 3.请求组件 ...
随机推荐
- 解决生成主键 id重复的解决办法
作者:董春秋链接:https://www.zhihu.com/question/30674667/answer/49082988来源:知乎著作权归作者所有,转载请联系作者获得授权. 全局id生成器.我 ...
- java8-2-Lambda表达式
java8的lambda表达式:使得代码更加紧凑:修改方法的能力:更好的支持多核处理(并行处理函数和filter\map\reduce) 例子1: java7中,list集合排序: public st ...
- VueJS 开发常见问题集锦
由于公司的前端开始转向 VueJS,最近开始使用这个框架进行开发,遇到一些问题记录下来,以备后用. 主要写一些 官方手册 上没有写,但是实际开发中会遇到的问题,需要一定知识基础. 涉及技术栈 CLI: ...
- SQL学习整理
SQL整理 SQL 对大小写不敏感! 一.对数据的操作 实现功能分类: 1. 增: 1.1 表存在,插入栏位: //插入新的行(按栏位的顺序插入) INSERT INTO Table_1 VALUES ...
- javascript学习中自己对作用域和作用域链理解
在javascript学习中作用域和作用域链还是相对难理解些,下面我关于javascript作用域和作用域链做一下详细介绍,给各位初学者答疑解惑. 首先我们介绍一下什么是作用域? 从字面上理解就是起 ...
- RedHat/CentOS 大文件拆分及合并与md5验证
[root@tdh55 mnt]# cd /opt/[root@tdh55 opt]# ll -h-rw-r--r--. 1 root root 7.5G May 12 11:19 TDH-Image ...
- Spring 获取propertise文件中的值
Spring 获取propertise文件中的值 Spring 获取propertise的方式,除了之前的博文提到的使用@value的注解注入之外,还可以通过编码的方式获取,这里主要说的是要使用Emb ...
- Discuz 3x 配置问题
1.注意config里面配置的路径 2.注意ucenter里面 的密钥要一直 3.IP 的选择
- 如何在sublime上运行php
这个问题虽然随便一搜都能有很多答案,但是我当时都没有顺利解决我会详细地写出较为容易理解和操作的步骤第一步,配置PHP环境变量如图一所示1.找到 我的电脑 -属性2.高级系统设置3.环境变量4.找到“系 ...
- 使用javadoc 报错:编码GBK的不可映射字符
运行命令:javadoc Test1.java 报错:编码GBK的不可映射字符 问题原因:类文件中带有非GBK字符 解决办法:javadoc -encoding utf-8 Test1.java