Elasticsearch 聚合学习之三:范围限定
欢迎访问我的 GitHub
这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos
本篇概览
在《Elasticsearch 聚合学习》系列的前面两篇文章中,我们熟悉了基本聚合操作,但这些操作都是面向索引中的全部数据(例如所有汽车销售记录一共有几种颜色的汽车),今天要学习的是如何对一定范围内的数据做聚合(例如以前是看所有汽车一共有几种颜色,现在只看福特汽车一共有几种颜色);
系列文章列表
环境信息
以下是本次实战的环境信息,请确保您的 Elasticsearch 可以正常运行:
操作系统:Ubuntu 18.04.2 LTS
JDK:1.8.0_191
Elasticsearch:6.7.1
Kibana:6.7.1
实战用的数据依然是一些汽车销售的记录,在第一章有详细的导入步骤,请参考操作,导入后您的 es 中的数据如下图:
本章概要
本篇聚焦查询范围限定,由以下内容构成:
不做限定时的默认范围;
最简单的查询范围
全局桶
使用过滤器
桶内使用过滤器
不做限定时的默认范围
下面是个普通的聚合请求,将文档按照 color 字段聚合,由于没有做任何范围限定,因此查询的是所有文档:
下面请求带上了查询条件 match_all**,匹配所有文档,和前面不带查询条件的请求达到了同样效果:
最简单的查询范围
前面提出了一个问题:福特汽车一共分为几种颜色?这就是最简单的范围限定聚合(限定了汽车品牌),查询 DSL 如下:
返回结果如下,只有福特汽车的聚合数据:
全局桶
如果想对比福特汽车的销售额和所有汽车的销售额,可以通过全局桶对所有文档做聚合,关键字是 global,全局桶的聚合不受范围限定的影响:
来看看结果:
不止是 query
前面的范围限定用到了 query,其实适用于查询的过滤器也能应用在聚合操作中,下面是过滤+聚合的查询,和前面一样,也是统计总销售和和福特汽车的销售额:
查询结果如下,和 query 的一样:
注意:虽然 query 和 filter 限定范围的结果是一样的,但是 filter 会忽略评分,并且有可能缓存结果数据,这些都是性能上的优势;
桶内 filter
学习桶内 filter 之前,先看看官方的布尔查询 DSL,如下所示,查询 JSON 对象的内部可以加入 filter,对查询结果做过滤:
桶内 filter 和布尔查询中的 filter 类似,对进入桶中的数据可以加入 filter,这样桶内的数据就是此 filter 过滤后的数据了;
举个例子,统计蓝色的福特汽车销售额,首先限定品牌范围,这个可以直接用之前的限定方式,然后在桶内加入一个 filter,只保留颜色为蓝色的文档:
返回结果如下,可见 hits.total 等于 2,表示查询到了两个文档,但是 sales.doc_count 等于 1,表示桶内 filter 作用后再桶内只剩下一个文档了:
后过滤器(post_filter)
还有一种特殊的 filter,名为 post_filter,其作用描述如下:
正常的聚合:先查询,得到查询结果 A,再用 A 做聚合操作得到结果 B,最后返回 B 和 A;
带有 post_filter 的聚合:先查询,得到查询结果 A,再用 A 做聚合操作得到结果 B,然后用 A 做过滤得到 C(过滤条件就是 post_filter),最后返回 B 和 C;
可见无论是否使用 post_filter,返回的聚合结果都是根据 A 生成的 B,不同之处在于用了 post_filter 就不返回 A,而是返回 A 的过滤结果;
以下是来自《Elasticsearch 权威指南》的 post_filter 示例:
值得注意得是:如果只做查询不做聚合,post_filter 的作用和我们常用的 filter 是类似的,但由于 post_filter 是在查询之后才会执行,所以 post_filter 不具备 filter 对查询带来的好处(忽略评分、缓存等),因此,在普通的查询中不要用 post_filter 来替代 filter;
如果您向进一步了解 post_filter,请参考《理解elasticsearch的post_filter》
至此,带有范围限定的聚合操作实战就全部完成了,目前所有示例的结果都是默认排序的,接下来的章节将一起学习了解如何对聚合结果做排序。
欢迎关注 InfoQ:程序员欣宸
版权声明: 本文为 InfoQ 作者【程序员欣宸】的原创文章。
原文链接:【http://xie.infoq.cn/article/35141a2284af93f609db6b14c】。文章转载请联系作者。
评论