最近项目里有用到ES,顺便简单学习了一下基础的查询以及执行过程,对比是一种很好的学习方法,所以我们先从一个熟悉的SQL开始:
SELECT COUNT(DISTINCT a), AVG(a) ...
FROM t
WHERE a BETWEEN (1, 10) AND b = 2 OR c = 3
GROUP BY a, b, c
HAVING a > 3
ORDER BY b
LIMIT 0, 10
以上就是我们工作中经常使用的一个比较完整的SQL,此次分析不涉及join,子查询,以及ES非结构化查询等,本文涉及到Trie树,Skip List,倒排索引,BKD树,正排索引等数据结构知识,建议先去了解相关的数据结构,下面对DSL中的相应的功能进行逐个分析。
一、天然分布式
首先,ES是天然分布式的结构,所以我先从宏观的角度来介绍一下ES的查询过程,然后在深入到各个分片内部的执行过程分析。
- 客户端发送一个 search 请求到 Node 3 , Node 3 会创建一个大小为 from + size 的空优先队列。
- Node 3 将查询请求转发到索引的每个主分片或副本分片中。每个分片在本地执行查询并添加结果到大小为 from + size 的本地有序优先队列中。
- 每个分片返回各自优先队列中所有文档的 ID 和排序值给协调节点,也就是 Node 3 ,它合并这些值到自己的优先队列中来产生一个全局排序后的结果列表。
- 协调节点辨别出哪些文档需要被取回并向相关的分片提交多个 GET 请求。
- 每个分片加载并丰富文档,如果有需要的话,接着返回文档给协调节点。
- 一旦所有的文档都被取回了,协调节点返回结果给客户端。
二、SELECT -> _source
ES可以使用_source参数指定需要返回的字段,比如:
{
"_source":