ElasticSearch聚合分析
聚合用于分析查询结果集的统计指标,我们以观看日志分析为例,介绍各种常用的ElasticSearch聚合操作。
目录:
首先展示一下我们要分析的文档结构:
{
"video_id": 1289643545120062253, // 视频id
"video_uid": 3931482202390368051, // 视频发布者id
"uid": 47381776787453866, // 观看用户id
"time": 1533891263224, // 时间发生时间
"watch_duration": 30 // 观看时长
}
每个文档记录了一个观看事件,我们通过聚合分析用户的观看行为。
ElasticSearch引入了两个相关概念:
- 桶(Buckets): 满足特定条件的文档的集合
- 指标(Metrics): 桶中文档的统计值,如特定字段的平均值
查询用户观看视频数和观看时长
首先用sql语句描述这个查询:
SELECT uid, count(*) as view_count
FROM view_log
WHERE time >= #{since} AND time <= #{to}
GROUP BY uid;
ES 查询:
GET /view_log/_search
{
"size" : 0,
"query": {
"range": {
"time": {
"gte": 0, // since
"lte": 0 // to
}
}
},
"aggs": {
"agg": { // agg为聚合的名称
"terms": { // 聚合的条件为 uid 相同
"field": "uid"
}
}
}
}
response:
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 100000,
"max_score": 0,
"hits": []
},
"aggregations": {
"agg": {
"buckets": [
{
"key": 21836334489858688,
"doc_count": 4026
},
{
"key": 31489302390368051,
"doc_count": 2717
}
]
}
}
result.aggregations.agg.buckets列表中包含了查询的结果。
因为我们按照terms:uid进行聚合,每个bucket为uid相同的文档集合,key字段即为uid。
doc_count 字段表明bucket中文档的数目即sql语句中的count(*) as view_count。
我们可以为查询添加额外的统计指标, sql描述:
SELECT uid, count(*) as view_count, avg(watch_duration) as avg_duration
FROM view_log
WHERE time >= #{since} AND time <= #{to}
GROUP BY uid;
ES 查询:
GET /view_log/_search
{
"size" : 0,
"query": {
"range": {
"time": {
"gte": 0, // since
"lte": 0 // to
}
}
},
"aggs": {
"agg": { // agg为聚合的名称
"terms": { // 聚合的条件为 uid 相同
"field": "uid"
},
"aggs": { // 添加统计指标(Metrics)
"avg_duration": {
"avg": { // 统计 watch_duration 的平均值
"field": "watch_duration"
}
}
}
}
}
}
response:
{
"took": 10,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 100000,
"max_score": 0,
"hits": []
},
"aggregations": {
"agg": {
"buckets": [
{
"key": 21836334489858688,
"doc_count": 4026,
"avg_duration": {
"value": 12778.882352941177
}
},
{
"key": 31489302390368051,
"doc_count": 2717,
"avg_duration": {
"value": 2652.5714285714284
}
}
]
}
}
avg_duration.value 表示 watch_duration 的平均值即该用户的平均观看时长。
聚合分页器
在实际应用中用户的数量非常惊人, 不可能通过一次查询得到全部结果因此我们需要分页器分批取回:
GET /view_log/_search
{
"size" : 0,
"query": {
"range": {
"time": {
"gte": 0, // since
"lte": 0 // to
}
}
},
"aggs": {
"agg": {
"terms": {
"field": "uid",
"size": 10000, // bucket 的最大个数
"include": { // 将聚合结果分为10页,序号为[0,9], 取第一页
"partition": 0,
"num_partitions": 10
}
},
"aggs": {
"avg_duration": {
"avg": {
"field": "watch_duration"
}
}
}
}
}
}
上述查询与上节的查询几乎完全相同,只是在aggs.agg.terms字段中添加了include字段进行分页。
查询视频uv
单个视频uv
uv是指观看一个视频的用户数(unique visit),与此相对没有按照用户去重的观看数称为pv(page visit)。
用SQL语句来描述:
SELECT video_id, count(*) as pv, count(distinct uid) as uv
FROM view_log
WHERE video_id = #{video_id};
ElasticSearch可以方便的进行count(distinct)查询:
GET /view_log/_search
{
"aggs": {
"uv": {
"cardinality": {
"field": "uid"
}
}
}
}
response:
{
"took": 255,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 17579,
"max_score": 0,
"hits": []
},
"aggregations": {
"uv": {
"value": 11
}
}
}
批量查询视频uv
ElasticSearch也可以批量查询count(distinct), 先用SQL进行描述:
SELECT video_id, count(*) as pv, count(distinct uid) as uv
FROM view_log
GROUP BY video_id;
查询:
GET /view_log/_search
{
"size": 0,
"aggs": {
"video": {
"terms": {
"field": "video_id"
},
"aggs": {
"uv": {
"cardinality": {
"field": "uid"
}
}
}
}
}
}
response:
{
"took": 313,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 16940,
"max_score": 0,
"hits": []
},
"aggregations": {
"video": {
"buckets": [
{
"key": 25417499722062, // 视频id
"doc_count": 427, // 视频观看次数 pv
"uv": {
"value": 124 // 观看视频的用户数 uv
}
},
{
"key": 72446898144,
"doc_count": 744,
"uv": {
"value":233
}
}
]
}
}
}
Having查询
SQL可以使用HAVING语句根据聚合结果进行过滤,ElasticSearch可以使用pipeline aggregations达到此效果不过语法较为繁琐。
根据 count 进行过滤
使用SQL查询观看超过200次的视频:
SELECT video_id, count(*) as view_count
FROM view_log
GROUP BY video_id
HAVING count(*) > 200;
GET /view_log/_search
{
"size": 0,
"aggs": {
"view_count": {
"terms": {
"field": "video_id"
},
"aggs": {
"having": {
"bucket_selector": {
"buckets_path": { // 选择 view_count 聚合的 doc_count 进行过滤
"view_count": "_count"
},
"script": {
"source": "params.view_count > 200"
}
}
}
}
}
}
}
response:
{
"took": 83,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 775,
"max_score": 0,
"hits": []
},
"aggregations": {
"view_count": {
"buckets": [
{
"key": 35025417499764062,
"doc_count": 529
},
{
"key": 19913672446898144,
"doc_count": 759
}
]
}
}
}
ElasticSearch实现类似HAVING查询的关键在于使用bucket_selector选择聚合结果进行过滤。
根据其它指标进行过滤
接下来我们尝试查询平均观看时长大于5分钟的视频, 用SQL描述该查询:
SELECT video_id FROM view_log
GROUP BY video_id
HAVING avg(watch_duration) > 300;
GET /view_log/_search
{
"size": 0,
"aggs": {
"video": {
"terms": {
"field": "video_id"
},
"aggs": {
"avg_duration": {
"avg": {
"field": "watch_duration"
}
},
"avg_duration_filter": {
"bucket_selector": {
"buckets_path": {
"avg_duration": "avg_duration"
},
"script": {
"source": "params.avg_duration > 200"
}
}
}
}
}
}
}
response:
{
"took": 137,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"skipped": 0,
"failed": 0
},
"hits": {
"total": 255,
"max_score": 0,
"hits": []
},
"aggregations": {
"video": {
"buckets": [
{
"key": 5417499764062,
"doc_count": 91576,
"avg_duration": {
"value": 103
}
},
{
"key": 19913672446898144,
"doc_count": 15771,
"avg_duration": {
"value": 197
}
}
]
}
}
}
ElasticSearch聚合分析的更多相关文章
- ElasticSearch 聚合分析
公号:码农充电站pro 主页:https://codeshellme.github.io ES 中的聚合分析(Aggregations)是对数据的统计分析功能,它的优点是实时性较高,相比于 Hadoo ...
- ElasticSearch聚合分析API——非常详细,如果要全面了解的话,最好看这个
转自:http://www.tianyiqingci.com/2016/04/11/esaggsapi/ 前言 说完了ES的索引与检索,接着再介绍一个ES高级功能API – 聚合(Aggregatio ...
- Elasticsearch 6.x版本全文检索学习之聚合分析入门
1.什么是聚合分析? 答:聚合分析,英文为Aggregation,是es除搜索功能外提供的针对es数据做统计分析的功能.特点如下所示: a.功能丰富,提供Bucket.Metric.Pipeline等 ...
- Elasticsearch 之聚合分析入门
本文主要介绍 Elasticsearch 的聚合功能,介绍什么是 Bucket 和 Metric 聚合,以及如何实现嵌套的聚合. 首先来看下聚合(Aggregation): 什么是 Aggregati ...
- elasticsearch系列六:聚合分析(聚合分析简介、指标聚合、桶聚合)
一.聚合分析简介 1. ES聚合分析是什么? 聚合分析是数据库中重要的功能特性,完成对一个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最大值.最小值,计算和.平均值等.ES作为 ...
- ElasticStack学习(八):ElasticSearch索引模板与聚合分析初探
一.Index Template与Dynamic Template的概念 1.Index Template:它是用来根据提前设定的Mappings和Settings,并按照一定的规则,自动匹配到新创建 ...
- Elasticsearch系列---常见搜索方式与聚合分析
概要 本篇主要介绍常见的6种搜索方式.聚合分析语法,基本是上机实战,可以和关系型数据库作对比,如果之前了解关系型数据库,那本篇只需要了解搜索和聚合的语法规则就可以了. 搜索响应报文 以上篇建立的mus ...
- Elasticsearch学习笔记(三)聚合分析Agg
一.设置fielddata PUT /index/_mapping/type { "properties":{ "fieldName" ...
- Elasticsearch学习之深入聚合分析四---案例实战
1. 需求:比如有一个网站,记录下了每次请求的访问的耗时,需要统计tp50,tp90,tp99 tp50:50%的请求的耗时最长在多长时间tp90:90%的请求的耗时最长在多长时间tp99:99%的请 ...
随机推荐
- java多线程系列7 高级同步工具(1)信号量Semaphore
Semaphore叫做信号量 可以控制某个资源可被同时访问的个数, acquire() 获取一个许可,得到许可才能执行后面的代码,如果没有就等待. release() 释放一个许可. 当信号量的只允许 ...
- python+selenium—webdriver入门(二)
本文中主要介绍webdriver常见的对象定位方法: 一.对象定位的目的 二.常见的对象定位方法 一.对象定位的目的: 1.操作对象 2.获得对象的属性,如:对象的class属性.name属性等 3. ...
- thymeleaf学习笔记:总结
Thymeleaf定义:Thymeleaf is a modern server-side Java template engine for both web and standalone envir ...
- mysql 在update中实现子查询的方式
当使用mysql条件更新时--最先让人想到的写法 UPDATE buyer SET is_seller=1 WHERE uid IN (SELECT uid FROM seller) 此语句是错误的, ...
- Codeforces828 A. Restaurant Tables
A. Restaurant Tables time limit per test 1 second memory limit per test 256 megabytes input standard ...
- 微信小程序scroll-view 横向和纵向scroll-view组件
scroll-view为滚动视图,分为水平滚动和垂直滚动.注意滚动视图垂直滚动时一定要设置高度否则的话scroll-view不会生效.滚动视图常用的地方一般都是Item项比较多的界面,比如我的模块 主 ...
- 【详细】Android入门到放弃篇-YES OR NO-》各种UI组件,布局管理器,单元Activity
问:达叔,你放弃了吗? 答:不,放弃是不可能的,丢了Android,你会心疼吗?如果别人把你丢掉,你是痛苦呢?还是痛苦呢?~ 引导语 有人说,爱上一个人是痛苦的,有人说,喜欢一个人是幸福的. 人与人之 ...
- 走你!Github 开源整合
加入知识星球,最好的分享交流平台哦~ <我的知识星球,最好的分享交流平台>,一年的服务平台,对于一个成年人来说,就是小费了(更多详情,请点击文章了解)~ 走你!Github 开源整合 1. ...
- 软件测试人员需要掌握的linux命令(一)
有些技能可以事半功倍,熟练的使用这些命令可以提高工作效率,并且结合这些命令对测试过程中遇到的问题进行一些初步的定位. 一:目录与文件操作: ls 使用权限:所有人功能 : 显示指定工作目录下之内容(列 ...
- Java匹马行天下——开篇
个人感言: 匹马行天下是我高中时候看过一部叫<九鼎记>的小说中的其中一个大章节标题,在整个这一章中,讲的是是主人公滕青山历经艰险,又心如磐石,一心修行,最后巅峰归来的故事.现在回想,依旧心 ...