前言

说完了ES的索引与检索,接着再介绍一个ES高级功能API – 聚合(Aggregations),聚合功能为ES注入了统计分析的血统,使用户在面对大数据提取统计指标时变得游刃有余。同样的工作,你在hadoop中可能需要写mapreduce或hive,在mongo中你必须得用大段的mapreduce脚本,而在ES中仅仅调用一个API就能实现了。

开始之前,提醒老司机们注意,ES原有的聚合功能Facets在新版本中将被正式被移除,抓紧时间用Aggregations替换Facets吧。Facets真的很慢!

1 关于Aggregations

Aggregations的部分特性类似于SQL语言中的group by,avg,sum等函数。但Aggregations API还提供了更加复杂的统计分析接口。

掌握Aggregations需要理解两个概念:

  • 桶(Buckets):符合条件的文档的集合,相当于SQL中的group by。比如,在users表中,按“地区”聚合,一个人将被分到北京桶或上海桶或其他桶里;按“性别”聚合,一个人将被分到男桶或女桶
  • 指标(Metrics):基于Buckets的基础上进行统计分析,相当于SQL中的count,avg,sum等。比如,按“地区”聚合,计算每个地区的人数,平均年龄等

对照一条SQL来加深我们的理解:

1
SELECT COUNT(color) FROM table GROUP BY color

GROUP BY相当于做分桶的工作,COUNT是统计指标。

下面介绍一些常用的Aggregations API。

2 Metrics

2.1 AVG

求均值。

1
2
3
4
5
6
GET /company/employee/_search
{
    "aggs" : {
        "avg_grade" : { "avg" : { "field" : "grade" } }
    }
}

执行结果

1
2
3
4
5
{
    "aggregations": {
        "avg_grade": {"value": 75}
    }
}

其他的简单统计API,如valuecount, max,min,sum作用与SQL中类似,就不一一解释了。

2.2 Cardinality

cardinality的作用是先执行类似SQL中的distinct操作,然后再统计排重后集合长度。得到的结果是一个近似值,因为考虑到在大量分片中排重的性能损耗Cardinality算法并不会load所有的数据。
1
2
3
4
5
6
7
{
    "aggs" : {
    "author_count" : {
        "cardinality" : {"field" : "author"}
    }
    }
}

2.3 Stats

返回聚合分析后所有有关stat的指标。具体哪些是stat指标是ES定义的,共有5项。

1
2
3
4
5
{
    "aggs" : {
    "grades_stats" : { "stats" : { "field" : "grade" } }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
{
    "aggregations": {
    "grades_stats": {
        "count": 6,
        "min": 60,
        "max": 98,
        "avg": 78.5,
        "sum": 471
    }
    }
}

2.4 Extended Stats

返回聚合分析后所有指标,比Stats多三个统计结果:平方和、方差、标准差

1
2
3
4
5
{
    "aggs" : {
    "grades_stats" : { "extended_stats" : { "field" : "grade" } }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
{
    "aggregations": {
    "grade_stats": {
        "count": 9,
        "min": 72,
        "max": 99,
        "avg": 86,
        "sum": 774,
        # 平方和
        "sum_of_squares": 67028,
        # 方差
        "variance": 51.55555555555556,
        # 标准差
        "std_deviation": 7.180219742846005,
        #平均加/减两个标准差的区间,用于可视化你的数据方差
        "std_deviation_bounds": {
        "upper": 100.36043948569201,
        "lower": 71.63956051430799
        }
    }
    }
}

2.5 Percentiles

百分位法统计,举例,运维人员记录了每次启动系统所需要的时间,或者,网站记录了每次用户访问的页面加载时间,然后对这些时间数据进行百分位法统计。我们在测试报告中经常会看到类似的统计数据

1
2
3
4
5
6
7
{
    "aggs" : {
    "load_time_outlier" : {
        "percentiles" : {"field" : "load_time"}
    }
    }
}

结果是

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
    "aggregations": {
    "load_time_outlier": {
        "values" : {
        "1.0": 15,
        "5.0": 20,
        "25.0": 23,
        "50.0": 25,
        "75.0": 29,
        "95.0": 60,
        "99.0": 150
        }
    }
    }
}

加载时间在15ms内的占1%,20ms内的占5%,等等。

我们还可以指定百分位的指标,比如只想统计95%、99%、99.9%的加载时间

1
2
3
4
5
6
7
8
9
10
{
    "aggs" : {
    "load_time_outlier" : {
        "percentiles" : {
        "field" : "load_time",
        "percents" : [95, 99, 99.9]
        }
    }
    }
}

2.6 Percentile Ranks

Percentile API中,返回结果values中的key是固定的0-100间的值,而Percentile Ranks返回值中的value才是固定的,同样也是0到100。例如,我想知道加载时间是15ms与30ms的数据,在所有记录中处于什么水平,以这种方式反映数据在集合中的排名情况。

1
2
3
4
5
6
7
8
9
10
{
    "aggs" : {
    "load_time_outlier" : {
        "percentile_ranks" : {
        "field" : "load_time",
        "values" : [15, 30]
        }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
{
    "aggregations": {
    "load_time_outlier": {
        "values" : {
        "15": 92,
        "30": 100
        }
    }
    }
}

3 Bucket

3.1 Filter

先过滤后聚合,类似SQL中的where,也有点象group by后加having。比如

1
2
3
4
5
6
7
8
9
10
{
    "aggs" : {
    "red_products" : {
        "filter" : { "term": { "color": "red" } },
        "aggs" : {
        "avg_price" : { "avg" : { "field" : "price" } }
        }
    }
    }
}

只统计红色衣服的均价。

3.2 Range

反映数据的分布情况,比如我想知道小于50,50到100,大于100的数据的个数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "aggs" : {
    "price_ranges" : {
        "range" : {
        "field" : "price",
        "ranges" : [
            { "to" : 50 },
            { "from" : 50, "to" : 100 },
            { "from" : 100 }
        ]
        }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
{
    "aggregations": {
    "price_ranges" : {
        "buckets": [
        {"to": 50, "doc_count": 2},
        {"from": 50, "to": 100, "doc_count": 4},
        {"from": 100, "doc_count": 4}
        ]
    }
    }
}

3.3 Missing

我们想找出price字段值为空的文档的个数。

1
2
3
4
5
6
7
{
    "aggs" : {
    "products_without_a_price" : {
        "missing" : { "field" : "price" }
    }
    }
}

执行结果

1
2
3
4
5
6
7
{
    "aggs" : {
    "products_without_a_price" : {
        "doc_count" : 10
    }
    }
}

3.4 Terms

针对某个字段排重后统计个数。

1
2
3
4
5
6
7
{
    "aggs" : {
    "genders" : {
        "terms" : { "field" : "gender" }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
12
{
    "aggregations" : {
    "genders" : {
        "doc_count_error_upper_bound": 0,
        "sum_other_doc_count": 0,
        "buckets" : [
        {"key" : "male","doc_count" : 10},
        {"key" : "female","doc_count" : 10},
        ]
    }
    }
}

3.5 Date Range

针对日期型数据做分布统计。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
    "aggs": {
    "range": {
        "date_range": {
        "field": "date",
        "format": "MM-yyy",
            "ranges": [
            { "to": "now-10M/M" },
            { "from": "now-10M/M" }
        ]
        }
    }
    }
}

这里的format参数是指定返回值的日期格式。

执行结果

1
2
3
4
5
6
7
8
9
10
{
    "aggregations": {
    "range": {
        "buckets": [
        {"to": 1.3437792E+12, "to_as_string": "08-2012","doc_count": 7},
        {"from": 1.3437792E+12, "from_as_string": "08-2012","doc_count": 2}
        ]
    }
    }
}

3.6 Global Aggregation

指定聚合的作用域与查询的作用域没有关联。因此返回结果中query命中的文档,与聚合的的统计结果是没有关系的。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
    "query" : {
    "match" : { "title" : "shirt" }
    },
    "aggs" : {
    "all_products" : {
        "global" : {},
        "aggs" : {
        "avg_price" : { "avg" : { "field" : "price" } }
        }
    }
    }
}

3.7 Histogram

跟range类似,不过Histogram不需要你指定统计区间,只需要提供一个间隔区间的值。好象不太好理解,看个例子就全明白了。

比如,以50元为一个区间,统计每个区间内的价格分布

1
2
3
4
5
6
7
8
9
10
{
    "aggs" : {
    "prices" : {
        "histogram" : {
        "field" : "price",
        "interval" : 50
        }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
12
{
    "aggregations": {
    "prices" : {
        "buckets": [
        {"key": 0, "doc_count": 2},
        {"key": 50, "doc_count": 4},
        {"key": 100, "doc_count": 0},
        {"key": 150, "doc_count": 3}
        ]
    }
    }
}

由于最高的价格没超过200元,因此最后的结果自动分为小于50,50到100,100到150,大于150共四个区间的值。

100到150区间的文档数为0个,我们想在返回结果中自动过滤该值,或者过滤偏小的值,可以添加一个参数”min_doc_count”,比如

1
2
3
4
5
6
7
8
9
10
11
{
    "aggs" : {
    "prices" : {
        "histogram" : {
        "field" : "price",
        "interval" : 50,
        "min_doc_count" : 1
        }
    }
    }
}

返回结果会自动将你设定的值以下的统计结果过滤出去。

3.8 Date Histogram

使用方法与Histogram类似,只是聚合的间隔区间是针对时间类型的字段。

1
2
3
4
5
6
7
8
9
10
11
{
    "aggs" : {
    "articles_over_time" : {
        "date_histogram" : {
        "field" : "date",
        "interval" : "1M",
        "format" : "yyyy-MM-dd"
        }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
11
{
    "aggregations": {
    "articles_over_time": {
        "buckets": [
        {"key_as_string": "2013-02-02","key": 1328140800000, "doc_count": 1},
        {"key_as_string": "2013-03-02","key": 1330646400000, "doc_count": 2},
        ...
        ]
    }
    }
}

3.9 IPv4 range

由于ES是一个企业级的搜索和分析的解决方案,在做大量数据统计分析时比如用户访问行为数据,会采集用户的IP地址,类似这样的数据(还有地理位置数据等),ES也提供了最直接的统计接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
{
    "aggs" : {
    "ip_ranges" : {
        "ip_range" : {
        "field" : "ip",
        "ranges" : [
            { "to" : "10.0.0.5" },
            { "from" : "10.0.0.5" }
        ]
        }
    }
    }
}

执行结果

1
2
3
4
5
6
7
8
9
10
{
    "aggregations": {
    "ip_ranges": {
        "buckets" : [
        {"to": 167772165, "to_as_string": "10.0.0.5","doc_count": 4},
        {"from": 167772165,"from_as_string": "10.0.0.5","doc_count": 6}
        ]
    }
    }
}

3.10 Return only aggregation results

在统计分析时我们有时候并不需要知道命中了哪些文档,只需要将统计的结果返回给我们。因此我们可以在request body中添加配置参数size。

1
2
3
4
5
6
7
8
9
curl -XGET 'http://localhost:9200/twitter/tweet/_search' -d '{
    "size": 0,
        "aggregations": {
        "my_agg": {
            "terms": {"field": "text"}
            }
    }
}
'

4 聚合缓存

ES中经常使用到的聚合结果集可以被缓存起来,以便更快速的系统响应。这些缓存的结果集和你掠过缓存直接查询的结果是一样的。因为,第一次聚合的条件与结果缓存起来后,ES会判断你后续使用的聚合条件,如果聚合条件不变,并且检索的数据块未增更新,ES会自动返回缓存的结果。

注意聚合结果的缓存只针对size=0的请求(参考3.10章节),还有在聚合请求中使用了动态参数的比如Date Range中的now(参考3.5章节),ES同样不会缓存结果,因为聚合条件是动态的,即使缓存了结果也没用了。

ElasticSearch聚合分析API相关推荐

  1. ElasticSearch聚合分析API——非常详细,如果要全面了解的话,最好看这个

    转自:http://www.tianyiqingci.com/2016/04/11/esaggsapi/ 前言 说完了ES的索引与检索,接着再介绍一个ES高级功能API – 聚合(Aggregatio ...

  2. Elasticsearch聚合分析Java Client

    本文基于Elasticsearch7.x 本文将上篇Elasticsearch聚合分析Rest API里的实例转化为Java Client Bucket Aggregation Bucket Aggr ...

  3. 聚合中返回source_大数据搜索与可视化分析(9)elasticsearch聚合分析Metric Aggregation...

    在上一篇文章中,我们介绍了<大数据搜索与可视化分析(8)kibana入门教程-2-Discover>,本文学习elasticsearch聚合分析,是对<大数据搜索与可视化分析(3)e ...

  4. 搜索引擎(Elasticsearch聚合分析)

    2019独角兽企业重金招聘Python工程师标准>>> 学习目标 掌握聚合分析的查询语法. 掌握指标聚合.桶聚合的用法 聚合分析简介 ES聚合分析是什么? 聚合分析是数据库中重要的功 ...

  5. ElasticSearch聚合分析

    聚合用于分析查询结果集的统计指标,我们以观看日志分析为例,介绍各种常用的ElasticSearch聚合操作. 目录: 查询用户观看视频数和观看时长 聚合分页器 查询视频uv 单个视频uv 批量查询视频 ...

  6. Elasticsearch聚合分析的精准性 shard_size设置

    衡量分布式统计算法的指标有3个:数据量.实时性和精准性.任何算法只能满足其中2个指标,ES为了数据的实时性,降低了聚合分析的精准性.由于ES的数据是分布在各个分片上的,coordinating节点无法 ...

  7. ElasticSearch实现商品搜索与聚合分析

    ElasticSearch实现商品搜索与聚合分析 Gitee地址:https://gitee.com/yuyuuyuy/micro-mall 文章目录 ElasticSearch实现商品搜索与聚合分析 ...

  8. Elasticsearch简单搜索以及聚合分析

    1.批量索引文档 如果你有大量文档要索引,你能通过批量 API(bulk API) 来批量提交它们.批量文档操作比单独提交请求显著更快,因为它极简了网络往返. 最佳的批量数量取决于许多因素:文档的大小 ...

  9. Elasticsearch 分页查询聚合分析

    分页查询 关于 Elasticsearch 分页查询,这几个问题经常被问到 问题1:想请问下,一次性获取索引上的某个字段的所有值(100 万左右),除了把 max_result_window 调大 , ...

最新文章

  1. 未来属于人工智能工程师,但成功转型不容易
  2. bzoj 1911: [Apio2010]特别行动队 2011-12-26
  3. oracle any 语法,Oracle Any/Some
  4. 区块链app源码_区块链app商城系统开发适用于哪些企业
  5. python不好用_Python用不好?看官方中文文档啦
  6. macOS 10.15 Catalina 获取App Store下载的安装包
  7. Python零基础爬虫速成②:批量爬取微信公众号图片(基于beautifulsoup爬取吉他谱)
  8. python word 英语音标_(完整word版)英语音标大全
  9. 9012,9013三极管总结
  10. oracle 新增字段 影响,Oracle 之 表新增字段后修改字段顺序
  11. 点击改变文本框选择内容,Jquery datatables 重新加载数据
  12. 四/六层板层叠设计思路
  13. 高并发系统的限流算法与实现
  14. js字符串格式化方法format
  15. 友善之臂(FriendlyArm)NanoPi无线网络设置
  16. lstm 能耗预测_预测能耗第一部分
  17. 英雄联盟手游有EDG那么牛吗?——基于评论的文本分析证据
  18. mac 安装node.js
  19. 介绍一种Android 平台 不需要获取imei imsi 无权限就能获取手机运营商的方法
  20. Spread for WPF-Silverlight 新功能使用指南

热门文章

  1. 积水成渊:用github gist收藏你的代码片段
  2. 我的世界服务器怎么发全部消息,我的世界服务器里起床战争怎么向所有人说话...
  3. 最新 955 不加班的公司名单(2022 版)
  4. linux 7分区 fdisk,CentOS7创建逻辑卷,fdisk分区方式。
  5. 万花哥特体繁黑执事中文字体_50多种免费的高质量哥特式和恐怖字体
  6. Heavy Pitch趣味漫画风格字体 for mac
  7. SAP第四代增强 BTE
  8. cocos2d-x Touch触屏事件
  9. 前端 H5 页面地图展示,只需要传入经纬度就可展示地图及周边生活娱乐
  10. 计算机时钟的工作原理,单片机的周期与系统时钟的工作原理