es笔记七之聚合操作之桶聚合和矩阵聚合_天天热推荐
本文首发于公众号:Hunter后端原文链接:es笔记七之聚合操作之桶聚合和矩阵聚合
桶(bucket)聚合并不像指标(metric)聚合一样在字段上计算,而是会创建数据的桶,我们可以理解为分组,根据某个字段进行分组,将符合条件的数据分到同一个组里。
桶聚合可以有子聚合,意思就是在分组之后,可以在每个组里再次进行聚合操作,聚合的数据就是每个组的数据。
(资料图片仅供参考)
以下是本篇笔记目录:
基本桶聚合操作过滤聚合多桶过滤聚合全局聚合直方图聚合嵌套聚合范围聚合稀有词聚合矩阵聚合1、基本桶聚合操作我们可以简单的先来进行一下桶聚合的操作,比如我们根据 age 字段对数据进行分组操作:
GET /bank/_search{ "size": 0, "aggs": { "bucket_age": { "terms": { "field": "age", "size": 20 } } }}返回的数据如下:
{ ... "aggregations" : { "bucket_age" : { "doc_count_error_upper_bound" : 0, "sum_other_doc_count" : 35, "buckets" : [ { "key" : 31, "doc_count" : 61 }, { "key" : 39, "doc_count" : 60 }, { "key" : 26, "doc_count" : 59 }, ... ] } }} 所有的数据在 aggregations.bucket_age.buckets 下,这是一个数组,key 的内容为 age 的值,doc_count 为该 age 值的数据条数。
其中,bucket_age 为我们定义的桶聚合的名称。
接下来我们介绍桶聚合和指标聚合的其他操作。
2、过滤聚合如果我们想针对某特定的数据进行聚合,那么就涉及数据的过滤,筛选出特定的数据进行聚合。
比如我们想筛选出 gender 的值为 "F" 的数据,然后对其进行取平均数的操作,我们可以使用 filter 来如下操作:
GET /bank/_search{ "size": 0, "aggs": { "bucket_gender": { "filter": {"term": {"gender.keyword": "F"}}, "aggs": { "avg_balance": {"avg": {"field": "balance"}} } } }}aggs.bucket_gender我们使用 filter 对数据进行了一个过滤,筛选出 gender 的值为 "F" 的数据。
注意,在这里,因为我们写入数据前,没有预先定义字段的类型,所以 es 中将其自动转化成 text 属性的字段,所以在查询的时候用到的是 gender.keyword,意思是对 gender 字段的内容作为整体进行筛选。
如果本身是 keyword 属性,就不用加 .keyword 来操作。
与 filter 同级的 aggs,进行针对筛选出的数据进行聚合的操作,这里我们用到的是平均值。
返回的数据如下:
... "aggregations" : { "bucket_gender" : { "doc_count" : 493, "avg_balance" : { "value" : 25623.34685598377 } } }}3、多桶过滤聚合在上一点我们过滤的是单个条件,gender="F" 的情况,如果我们想要实现多个过滤来操作,可以使用 filters,使用方法也不一样。
比如我们想分别对 gender 的值为 F 和 M 的数据进行均值操作,我们可以一步步来操作,我们先来通过 filters 实现两个桶的聚合:
GET /bank/_search{ "size": 0, "aggs": { "bucket_gender": { "filters": { "filters": { "female": {"term": {"gender.keyword": "F"}}, "male": {"term": {"gender.keyword": "M"}} } } } }}返回的数据就是两个桶,包含了两类数据的总数:
... "aggregations" : { "bucket_gender" : { "buckets" : { "female" : { "doc_count" : 493 }, "male" : { "doc_count" : 507 } } } }}如果想在此基础上接着对其进行均值计算,和前面的 filter 操作一样,在第一个 filters 同级的地方,加上我们的指标聚合操作:
GET /bank/_search{ "size": 0, "aggs": { "bucket_gender": { "filters": { "filters": { "female": {"term": {"gender.keyword": "F"}}, "male": {"term": {"gender.keyword": "M"}} } }, "aggs": { "avg_balance": {"avg": {"field": "balance"}} } } }}这样,在返回的桶的数据之内,还包含了一个均值的结果:
... "aggregations" : { "bucket_gender" : { "buckets" : { "female" : { "doc_count" : 493, "avg_balance" : { "value" : 25623.34685598377 } }, "male" : { "doc_count" : 507, "avg_balance" : { "value" : 25803.800788954635 } } } } }}这里我们因为 gender 只有 F 和 M 两个值,所以没有第三类数据,对于其他数据,比如 age,有很多值,除了某几种特定的值外,我们还想获取剩下的值的信息,如何操作呢?
这里使用到 other_bucket_key 这个参数,比如我们除了定义的 female 和 male,我们还定义一个 non_gender 字段来统计非 M 和 F 的值,我们可以这样操作:
GET /bank/_search{ "size": 0, "aggs": { "bucket_gender": { "filters": { "other_bucket_key": "non_gender", "filters": { "female": {"term": {"gender.keyword": "F"}}, "male": {"term": {"gender.keyword": "M"}} } } } }}返回的值如下:
... "aggregations" : { "bucket_gender" : { "buckets" : { "female" : { "doc_count" : 493, "avg_balance" : { "value" : 25623.34685598377 } }, "male" : { "doc_count" : 507, "avg_balance" : { "value" : 25803.800788954635 } }, "non_gender" : { "doc_count" : 0, "avg_balance" : { "value" : null } } } } }}4、全局聚合如果我们要在限定的范围内进行聚合,但是又想在全局范围内获取聚合数据进行比对。
比如说,我们在 gender="F" 的范围进行聚合操作:
GET /bank/_search{ "size": 0, "query": {"match": {"gender.keyword": "F"}}, "aggs": { "female_balance_avg": { "avg": { "field": "balance" } } }}这里通过 query 操作筛选 gender="F" 的数据,然后对 balance 字段进行聚合,如果同时我们想要获取所有数据的 balance 的平均值,我们可以使用 global 来操作,如下:
GET /bank/_search{ "size": 0, "query": {"match": {"gender.keyword": "F"}}, "aggs": { "total_balance_avg": { "global": {}, "aggs": { "avg_balance": { "avg": {"field": "balance"} } } }, "female_balance_avg": { "avg": { "field": "balance" } } }}这样就有两个数据来比对,结果如下:
... "aggregations" : { "female_balance_avg" : { "value" : 25623.34685598377 }, "total_balance_avg" : { "doc_count" : 1000, "avg_balance" : { "value" : 25714.837 } } }}5、直方图聚合这是个类似于直方图的区间桶的聚合操作。
比如对于 age 字段,我们想以 5 为步长进行聚合,如果 age 字段在 20-50 之间,那么返回的数据就会类似于 20-24,25-29,30-34... 以及落在这些区间的数据的数量。
而返回的每条数据并不会是一个区间,而是一个开始的数据,也就是说上面的例子会返回的 key 是 20,25,30 等。
比如我们想对 age 字段进行直方图聚合,步长为 5,用到的聚合的字段为 histogram,示例如下:
GET /bank/_search{ "size": 0, "aggs": { "age_histogram": { "histogram": { "field": "age", "interval": 5 } } }}在 histogram 聚合字段下,field 字段为我们要进行直方图聚合的字段,这里是 age 字段,interval 字段为进行划分的区间,我们定义为 5。
返回的数据如下:
... "aggregations" : { "age_histogram" : { "buckets" : [ { "key" : 20.0, "doc_count" : 225 }, { "key" : 25.0, "doc_count" : 226 } ... ] }} 注意:如果我们进行聚合的区间,比如说 25-29 之间聚合的数据是 0,那么 es 还是会返回这个区间,不过 doc_count 是 0,不会存在不返回这个区间 key 的情况。
最小 count 返回数据前面我们说了就算区间 count 数是0,这个区间也会返回,但同时我们也可以规定 min_doc_count 这个参数来返回只有当区间 count 数大于等于这个值的时候才返回数据。
假设 age 的区间数据如下:
20-24:5
25-29:0
30-34:2...
如果我们设置 min_doc_count=2,那么返回的区间 25-29则不会被返回,使用示例如下:
GET /bank/_search{ "size": 0, "aggs": { "age_histogram": { "histogram": { "field": "age", "interval": 5, "min_doc_count": 2 } } }}返回数据:
... "aggregations" : { "age_histogram" : { "buckets" : [ { "key" : 20.0, "doc_count" : 5 }, { "key" : 30.0, "doc_count" : 2 }, ... ] } }指定返回区间前面介绍的示例中,如果数据在 20-50 之间,那么返回的区间数据就从 20 开始计数(具体的 key 会根据 interval 的设置不一样,比如设置 Interval=5,key 就会是 20, 25, 30...,如果是设置 Interval=3,那么 key 就会是 18, 21, 24...)。
如果我们想从 0 开始计数,即便是 0-20 之间的计数为 0,也想要返回20之前 0-4,5-9 的数,或者想要返回 50 之后的数据,包括 50-54,55-59 这种,我们可以使用extended_bounds.min和 extended_bounds.max来限定返回数据的最大最小值,示例如下:
GET /bank/_search{ "size": 0, "aggs": { "age_histogram": { "histogram": { "field": "age", "interval": 5, "extended_bounds": { "min": 0, "max": 90 } } } }}这样返回的数据的区间就会在 0-90 之间,即便在全量数据的范围之外。
注意:因为在数据区间之外的数据为 0,想要扩展的区间返回显示,记得要将最小返回计数值 min_doc_count置为 0。
6、嵌套聚合嵌套聚合,这里针对的是 es 中数据字段为数组,数组元素里又嵌套为对象的情况,官方文档举了个例子,新建一个 products 的 index,数据结构如下:
PUT /products{ "mappings": { "properties" : { "resellers" : { "type" : "nested", "properties" : { "reseller" : { "type" : "text" }, "price" : { "type" : "double" } } } } }}接下来我们往里添加两条条数据:
PUT /products/_doc/0{ "name": "LED TV", "resellers": [ { "reseller": "companyA", "price": 350 }, { "reseller": "companyB", "price": 500 } ]}PUT /products/_doc/1{ "name": "LED TV", "resellers": [ { "reseller": "companyA", "price": 400 }, { "reseller": "companyB", "price": 250 } ]}然后我们想要在这两条数据里的 resellers 数组字段里的四个元素里获取 price 字段最小值,可以通过 nested.path 来指定 resellers 字段,然后进行聚合,使用示例如下:
GET /products/_search{ "size": 0, "query" : { "match" : { "name" : "led tv" } }, "aggs" : { "resellers" : { "nested" : { "path" : "resellers" }, "aggs" : { "min_price" : { "min" : { "field" : "resellers.price" } } } } }}7、范围聚合范围聚合,即 range 聚合。我们可以通过指定范围来返回各个桶的数据,这个操作和直方图聚合是类似的,不过这个操作更灵活,聚合的范围不会写死。
如果是希望步长固定,我们可以使用直方图聚合,比如0-4,5-9 这种,如果我们直接想要自定义的 0-7,8-19 这种我们想要定义的可以使用范围聚合。
还是使用 age 字段来操作,比如我们想要获取 小于27,28-35,大于36 这个范围,我们可以如下操作:
GET /bank/_search{ "size": 0, "aggs": { "age_range": { "range": { "field": "age", "ranges": [ {"to": 27}, {"from": 27, "to": 35}, {"from": 35} ] } } }}需要注意的是,from 的参数是开区间的,比如我们这里 from=27,那么逻辑就是 >27,如果区间两边没有限制,不填写相应的 from 和 to 参数即可,返回的 key 也会是 *-27 这种形式。
上面的命令返回的数据如下:r
... "aggregations" : { "age_range" : { "buckets" : [ { "key" : "*-27.0", "to" : 27.0, "doc_count" : 326 }, { "key" : "27.0-35.0", "from" : 27.0, "to" : 35.0, "doc_count" : 384 }, { "key" : "35.0-*", "from" : 35.0, "doc_count" : 290 } ] } }}如果想要返回的数据以 key:{} 的形式返回,可以加上 keyed=true 参数:
GET /bank/_search{ "size": 0, "aggs": { "age_range": { "range": { "field": "age", "keyed": true, "ranges": [ {"to": 27}, {"from": 27, "to": 35}, {"from": 35} ] } } }}桶的子指标聚合在上面的桶聚合操作之后,我们还可以对每个桶进行子指标聚合,比如说最大最小值,平均值,或者统计值等,以下是个操作示例:
GET /bank/_search{ "size": 0, "aggs": { "age_range": { "range": { "field": "age", "ranges": [ {"to": 27}, {"from": 27, "to": 35}, {"from": 35} ] }, "aggs": { "age_stats": { "stats": { "field": "age" } } } } }}进行指标聚合的范围是分到每个桶的数据。
8、稀有词聚合rare terms aggregation,这个的概念大概是这样的,比如我们根据 age 字段进行聚合,统计他们在文档中出现的次数,我们想要获取出现次数最少的几个,或者指定出现次数少于 50 的 age 值,就可以用到这个操作。
接下来我们对 age 字段进行这样的操作,只获取出现次数少于 50 的数据,示例如下:
GET /bank/_search{ "size": 0, "aggs": { "rare_age": { "rare_terms": { "field": "age", "max_doc_count": 50 } } }}这个的关键字是 rare_terms,rare_age 是我们指定的聚合名称,其下 field 是我们进行聚合字段,在这里是 age 字段,max_doc_count 则是我们指定的出现次数最大的值。
返回的数据会按照 doc_count 正序排列返回,大致如下:
... "aggregations" : { "rare_age" : { "buckets" : [ { "key" : 29, "doc_count" : 35 }, { "key" : 27, "doc_count" : 39 }, { "key" : 38, "doc_count" : 39 }, ...范围过滤我们还可以使用过滤的方式来指定或者排除某些值,这个操作是支持正则的,但经过测试,发现按照官方文档使用正则的 * 来筛选数据并不能真正起作用,所以这里我们介绍使用列表来实现过滤。
比如我们指定的 age 范围是 [29, 27, 24],使用 include:
GET /bank/_search{ "size": 0, "aggs": { "rare_age": { "rare_terms": { "field": "age", "max_doc_count": 51, "include": [29, 27, 24] } } }}如果我们要排除的 age 范围是 [29, 27, 24],使用 exclude:
GET /bank/_search{ "size": 0, "aggs": { "rare_age": { "rare_terms": { "field": "age", "max_doc_count": 51, "exclude": [29, 27, 24] } } }}9、矩阵聚合矩阵聚合是很小的一部分,这里直接介绍一下。
前面在指标聚合的介绍中,有一个聚合统计汇总,其中介绍了一个参数是 stats,会返回对应字段的最大值、最小值、总数等数据,矩阵聚合 matrix 可以理解成是多个字段的 stats 的集合,会缺少一些统计值,但是返回的值更偏统计学方面的用途。
使用示例如下:
GET /bank/_search{ "size": 0, "aggs": { "field_statis": { "matrix_stats": { "fields": ["age", "balance"] } } }}返回的数据如下:
... "aggregations" : { "field_statis" : { "doc_count" : 1000, "fields" : [ { "name" : "balance", "count" : 1000, "mean" : 25714.837000000014, "variance" : 1.9757153733576667E8, "skewness" : -0.009992486755643138, "kurtosis" : 1.8088323899074914, "covariance" : { "balance" : 1.9757153733576667E8, "age" : -2845.650777777781 }, "correlation" : { "balance" : 1.0, "age" : -0.033676422195874786 } }, { "name" : "age", "count" : 1000, ... } ...其中,各参数的释义如下:
count: 总数
mean: 平均值
variance: 方差
skewness: 偏度
kurtosis: 峰度
covariance: 协方差
correlation: 与其他字段的相关性,比如 age 到 age 字段的相关性就是 1.0
如果想获取更多后端相关文章,可扫码关注阅读:
标签:
es笔记七之聚合操作之桶聚合和矩阵聚合_天天热推荐
2023-05-26
速看:华西证券(002926):5月25日北向资金减持76.41万股
2023-05-26
崔才人|每日资讯
2023-05-26
龟苓膏正宗做法_龟苓膏的做法简介介绍 全球热门
2023-05-26
兰州中考查分电话(最新)|环球新要闻
2023-05-26
彭州市法院“牡丹讲坛”提档升级|观焦点
2023-05-26
全球今头条!我发现互联网工作的性价比还在持续走低,没看到好转的迹象
2023-05-26
实时焦点:踉踉跄跄的拼音_踉踉跄跄
2023-05-26
今日最新!自制葡萄酒的正确方法与详细步骤_自制葡萄酒
2023-05-25
骏卡可以充值什么游戏_骏卡充值q币 热门看点
2023-05-25
速看:华西证券(002926):5月25日北向资金减持76.41万股
崔才人|每日资讯
龟苓膏正宗做法_龟苓膏的做法简介介绍 全球热门
兰州中考查分电话(最新)|环球新要闻
彭州市法院“牡丹讲坛”提档升级|观焦点
全球今头条!我发现互联网工作的性价比还在持续走低,没看到好转的迹象
实时焦点:踉踉跄跄的拼音_踉踉跄跄
今日最新!自制葡萄酒的正确方法与详细步骤_自制葡萄酒
骏卡可以充值什么游戏_骏卡充值q币 热门看点
Blasphemous II 感觉更聪明,更快,甚至更有罪
上海地铁回应市民建议设女性车厢 暂无条件实现!!_世界新视野
亿缕阳光|相信自己会发光 世界信息
联想YOGA发新品,YOGA Book 9i双屏设计突破无限场景 当前速看
王石新增投资深圳碳减排企业
银星能源:公司主营新能源发电业务,为社会提供清洁能源,没有出口业务 天天热消息
屹立潮头 傲视同级 | 全新长轴距GLC SUV诚意“变身”
世界消息!一个小区的12年垃圾分类实践
全球速读:官方:国足亚运队6月15日、6月19日对阵韩国U24
做黑脸娃娃的原理是什么_黑脸娃娃工作原理 每日速看
快资讯:运河美食·天津丨狗不理、嘎巴菜,津菜津宴唤醒一天精气神
TCL华星闪耀SID2023会场,OLED/MLED多项创新显示技术领先全球
“两高两部”联合发布意见 办理性侵害未成年人刑事案件 坚持这些原则→-全球看点
长城汽车长城汽车被多家机构看涨,TA有什么领涨“密码”?-全球今亮点
当下无法绕开的一个话题叫做:内容驱动消费_每日速读
可喜安麦饭石床垫 可喜安麦饭石床垫价格
中国天楹:5月24日融资买入3498.68万元,融资融券余额6.76亿元-世界通讯
今日观点!赢球又赢人!他一句话让MVP成为笑话!
川崎VS凯越“针尖对麦芒” 2023北京摩博会VLOG 环球讯息
78岁千万富翁越狱计划泡汤,情节堪比电影剧本
- 全球今头条!新航季让航司和机场“忙”了起来
- 资讯:汉钟精机(002158):5月24日北向资金增持9.64万股
- 环球速递!一加8pdc调光要开吗(一加acepro有高频调光吗)
- 到2025年越南卫浴和浴室配件市场规模将达到6.852亿美元-当前视点
- 闯红灯扣几分多久能查到_闯红灯扣几分|全球资讯
- 环球时讯:小鹏汽车:一季度总收入为40.3亿元 同比降45.9%
- 05.25 上證指數、創業板指數 實戰技術應用
- 放弃王玉玲唱歌
- 当前快播:超聚光 XMAGE 影像助力 华为 P60 Pro 让影像旗舰和轻薄统一战线
- 【中超】尹鸿博谢维军进球 津门虎客场1比1梅州客家|世界微动态
- 有编制!今年河南省特招3156名医学院校毕业生
- 明后两天湖南北部有降雨过程 雨水难挡升温势头 世界热门
- 环球短讯!IT'S TiME此刻,智未来丨全球销冠卡罗拉智慧新生 售价11.68万元起
- 探宝游园!湖北国土资源职院走进小学举办职教周活动
- 宁德时代:麒麟电池已量产交付极氪4C麒麟电池将在理想首个纯电动平台搭载-全球通讯
- 传香港银行调高按揭回赠 中原按揭:银行进一步上调现金回赠的空间不大|消息
- 市民社保卡遗失 河西民警查监控数小时帮找回-天天精选
- 坦克世界工具箱 实时焦点
- 天天快看点丨叹气、抖腿、跷二郎腿……这7个小动作很伤身,快改掉!
- 恭喜Cryin!重回赛场!IG官宣:中单Cryin正式加入!粉丝拍手叫好_环球快播
- 瑞丰光电董秘回复:目前公司的募投项目已按项目计划投产
- 白宫:拜登已听取关于“白宫附近安全护栏遭卡车冲撞”简报
- 世界快资讯:【早盘快报】昨日A股三大指数集体收跌,医疗板块逆势上扬,创新药ETF易方达(516080)收获三连阳!
- 【环球新视野】表哥我出来了哦是什么梗
- Oncoclínicas集团一季度实现净收入4100万雷亚尔 全球播资讯
- 【世界热闻】没啥作业,不上课外班,这群“不努力”的孩子,让我看到鸡娃的最高境界
- 环球热文:恒生指数开盘跌0.78% 恒生科技指数跌1%
- 抵津等待手术 14名西藏先心病患儿来津“修心”
- 上海电气:海上风电累计并网容量突破1000万千瓦
- 焦点!中国男子1000米世界纪录_男子1000米世界纪录
- 楗木_楗
- 珠光控股(01176.HK):5月23日南向资金增持59万股 焦点消息
- 李天一出狱后首现身,身材高大超过李双江,梦鸽喜笑颜开心情大好 今日讯
- 世界上最早的纸币产生在哪里?
- 今日精选:usb无线网卡插上没反应(usb无线网卡)
- 当前看点!创业板指跌逾1%
- 半夏投资李蓓回应净值“暴跌”:风控很严,期待我倒霉的要失望了
- 滁州市琅琊区多点发力推进社会保险扩面提质-全球焦点
- “三角梅大楼”成网红打卡地背后:240户居民10年打造出“花草童话”
- iG战队官宣Cryin加入 新视野
- 菲律宾科技大学博士【项目简章】
- 【时快讯】大盘全天调整!这个板块却在被资金热炒 能持续吗?
- “最美北外滩”虹口区文化馆服务宣传周启动
- 当前关注:铁狮门和辉盛国际向华润置地附属收购“深润大厦”项目的长租公寓部分
- 世界滚动:西城区举办“京剧发祥地”品牌建设主题论坛
- 深耕课堂,胜西小学文兴分校与胜西小学联合教研促成长
- 南非商界就八级限电敲响警钟 环球速讯
- 国泰空乘歧视非英语乘客?媒体:看人下菜碟,损人也不会利己
- 国产护肤品牌黛莱皙频频获奖!再次斩获年度护肤品牌奖
- 世界快看:涉黄短信“轰炸”调查:色情直播App钓鱼,精准“筛”男粉
