1.优化聚合查询示例

假设我们现在有一些关于电影的数据集,每条数据里面会有一个数组类型的字段存储表演该电影的所有演员的名字。
{
"actors" : [
"Fred Jones",
"Mary Jane",
"Elizabeth Worthing"
]
}

如果我们想要查询出演影片最多的十个演员以及与他们合作最多的演员,使用聚合是非常简单的:

     {
"aggs" : {
"actors" : {
"terms" : {
"field" : "actors",
"size" :
},
"aggs" : {
"costars" : {
"terms" : {
"field" : "actors",
"size" :
}
}
}
}
}
}
     这会返回前十位出演最多的演员,以及与他们合作最多的五位演员。这看起来是一个简单的聚合查询,最终只返回 50 条数据!
     但是, 这个看上去简单的查询可以轻而易举地消耗大量内存,我们可以通过在内存中构建一个树来查看这个 terms 聚合。 actors 聚合会构建树的第一层,每个演员都有一个桶。然后,内套在第一层的每个节点之下, costar 聚合会构建第二层,每个联合出演一个桶。这意味着每部影片会生成 n2 个桶!
 

2.深度优先和广度优先原理

     Elasticsearch 允许我们改变聚合的 集合模式 ,就是为了应对这种状况。 我们之前展示的策略叫做 深度优先 ,它是默认设置, 先构建完整的树,然后修剪无用节点。 深度优先 的方式对于大多数聚合都能正常工作,但对于如我们演员和联合演员这样例子的情形就不太适用。
     为了应对这些特殊的应用场景,我们应该使用另一种集合策略叫做 广度优先 。这种策略的工作方式有些不同,它先执行第一层聚合, 再 继续下一层聚合之前会先做修剪。
 
     在我们的示例中, actors 聚合会首先执行,在这个时候,我们的树只有一层,但我们已经知道了前 10 位的演员!这就没有必要保留其他的演员信息,因为它们无论如何都不会出现在前十位中。因为我们已经知道了前十名演员,我们可以安全的修剪其他节点。修剪后,下一层是基于 它的 执行模式读入的,重复执行这个过程直到聚合完成。
     要使用广度优先,只需简单 的通过参数 collect 开启:
{
"aggs" : {
"actors" : {
"terms" : {
"field" : "actors",
"size" : ,
"collect_mode" : "breadth_first"
},
"aggs" : {
"costars" : {
"terms" : {
"field" : "actors",
"size" :
}
}
}
}
}
}
     广度优先仅仅适用于每个组的聚合数量远远小于当前总组数的情况下,因为广度优先会在内存中缓存裁剪后的仅仅需要缓存的每个组的所有数据,以便于它的子聚合分组查询可以复用上级聚合的数据
     广度优先的内存使用情况与裁剪后的缓存分组数据量是成线性的。对于很多聚合来说,每个桶内的文档数量是相当大的。 想象一种按月分组的直方图,总组数肯定是固定的,因为每年只有12个月,这个时候每个月下的数据量可能非常大。这使广度优先不是一个好的选择,这也是为什么深度优先作为默认策略的原因。
     针对上面演员的例子,如果数据量越大,那么默认的使用深度优先的聚合模式生成的总分组数就会非常多,但是预估二级的聚合字段分组后的数据量相比总的分组数会小很多所以这种情况下使用广度优先的模式能大大节省内存,从而通过优化聚合模式来大大提高了在某些特定场景下聚合查询的成功率。

ES系列九、ES优化聚合查询之深度优先和广度优先的更多相关文章

  1. 面试系列九 es 提高查询效率

    ,es性能优化是没有什么银弹的,啥意思呢?就是不要期待着随手调一个参数,就可以万能的应对所有的性能慢的场景.也许有的场景是你换个参数,或者调整一下语法,就可以搞定,但是绝对不是所有场景都可以这样. 一 ...

  2. Es学习第九课, 聚合查询和复合查询

    ES除了实现前几课的基本查询,也可以实现类似关系型数据库的聚合查询,如平均值sum.最小值min.最大值max等等 我们就用上一课的数据作为参考来举例 聚合查询 sum聚合 sum是一个求累加值的聚合 ...

  3. ElasticSearch实战系列五: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合

    Title:ElasticSearch实战系列四: ElasticSearch的聚合查询基础使用教程之度量(Metric)聚合 前言 在上上一篇中介绍了ElasticSearch实战系列三: Elas ...

  4. 58.海量bucket优化机制:从深度优先到广度优先

    当buckets数量特别多的时候,深度优先和广度优先的原理,图解 假如我们有如下数据数据:每个演员的每个电影的评论. 现在我们的需求是找到前10名的演员所演的电影的评论.这是一个两层聚合题.     ...

  5. 重学ES系列之函数优化

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  6. mysql 开发进阶篇系列 23 应用层优化与查询缓存

    一.概述 前面章节介绍了很多数据库的优化措施,但在实际生产环境中,由于数据库服务器本身的性能局限,就必须要对前台的应用来进行优化,使得前台访问数据库的压力能够减到最小. 1. 使用连接池 对于访问数据 ...

  7. ES系列目录

    ES系列一.CentOS7安装ES 6.3.1 ES系列二.CentOS7安装ES head6.3.1 ES系列三.基本知识准备 ES系列四.ES6.3常用api之文档类api ES系列五.ES6.3 ...

  8. ES[7.6.x]学习笔记(十)聚合查询

    聚合查询,它是在搜索的结果上,提供的一些聚合数据信息的方法.比如:求和.最大值.平均数等.聚合查询的类型有很多种,每一种类型都有它自己的目的和输出.在ES中,也有很多种聚合查询,下面我们看看聚合查询的 ...

  9. ElasticSearch实战系列九: ELK日志系统介绍和安装

    前言 本文主要介绍的是ELK日志系统入门和使用教程. ELK介绍 ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件.新增了一 ...

随机推荐

  1. Linux中使用Electronic WeChat客户端

    微信推出了Windows版和Mac版,一直没有推出也不会推出Linux版本,这就催生了Electronic WeChat(https://github.com/geeeeeeeeek/electron ...

  2. KMP 模式串匹配 失去匹配的瞬间你还有什么

    KMP: KMP算法是一种改进的字符串匹配算法,由D.E.Knuth,J.H.Morris和V.R.Pratt同时发现,因此人们称它为克努特——莫里斯——普拉特操作(简称KMP算法).KMP算法的关键 ...

  3. C# ADO.NET基础&实战

    什么是ADO.NET:数据库访问技术! 作用:通过程序来连接访问数据库! 一.基础: using System.Data.SqlClient;    //数据库连接命名空间 string connec ...

  4. win7(旗舰版)下,OleLoadPicture 加载内存中的图片(MagickGetImageBlob),返回值 < 0

    昨天去三哥家,想把拍好的照片缩小一下,我用很久前写的一个软件进行缩小,然后进行一次效果预览,这个时候弹出: Call OleLoadPicture Fail - loadPictureFromMW 奇 ...

  5. vi怎么查找关键字

    进入vi的命令模式,具体操作:编辑模式下键入“:”,此时进入命令模式 在命令模式下键入“/”.

  6. Educational Codeforces Round 42 (Rated for Div. 2) D. Merge Equals

    http://codeforces.com/contest/962/problem/D D. Merge Equals time limit per test 2 seconds memory lim ...

  7. SQL Server 2008 数据库回滚到某个时间点

    数据库回滚到时间的的前提: 事务日志完整,数据库在完整恢复模式下进行过一次完整备份,数据库没有进行过还原操作(惨痛教训). 当数据库误操作时,切记冷静,不然问题就是滚雪球, 在不做下一步错误前  可观 ...

  8. 高级Linux运维工程师必备技能(扫盲篇)

    高级Linux运维工程师必备技能(扫盲篇) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 在了解文件系统之前,我们要学习一下磁盘存储数据的方式,大家都知道文件从内存若要持久化存储的 ...

  9. 在eclipse中启动项目报java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError: PermGen space

    在我们启动项目的时候经常会出现内存溢出这个错误  设置一下内存就ok 错误信息 java.util.concurrent.ExecutionException: java.lang.OutOfMemo ...

  10. Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程

    待解决的问题 Spring session(redis存储方式)监听导致创建大量redisMessageListenerContailner-X线程 解决办法 为spring session添加spr ...