sum bucket
关于sum bucket 与Filter Aggregation 结合的写法分享
Elasticsearch • cq1988114 发表了文章 • 0 个评论 • 3015 次浏览 • 2019-09-19 00:14
"query": {
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"term": {
"delflag": 0
}
},
{
"term": {
"is_child": 1
}
}
],
"must_not":
}
}
}
},
"aggs": {
"valid_sales_people": {
"filter": {
"bool": {
"must_not": {
"terms": {
"status": [
0,
1,
7
]
}
}
}
},
"aggs": {
"render_people": {
"terms": {
"field": "uid",
"size": 2147483647
},
"aggs": {
"unique_people": {
"cardinality": {
"field": "uid"
}
}
}
},
"member_count": {
"sum_bucket": {
"buckets_path": "render_people>unique_people"
}
}
}
}
}
},
如代码所示,我希望对status not in (0,1,7)的uid(用户)进行聚合,并想得到uid桶种类的求和,那么member_count就应该与render_people同级,而不是把member_count放到和与valid_sales_people同一级。
如果将member_count 与valid_sales_people放到同一级,会报一个错:sum_bucket的第一个聚合必须是多桶聚合。究其原因,应该是加上filter aggregation后,valid_sales_people已不具有多桶聚合属性(因为附带了filter过滤条件),而其下的render_people则具有了多桶聚合属性。所以member_count应该与render_people放在同级,对应的buckets_path也自然改为render_people>unique_people
记一次“访问量超过1000的人数”统计,计算聚合桶的个数
Elasticsearch • ziyou 发表了文章 • 2 个评论 • 8440 次浏览 • 2019-08-01 18:45
前言
众所周知,在ES中有各种聚合方法能够是数据分析简单、高效。但是在繁杂的聚合方法中找到满足我们需求的那个,需要我们自己去实践。下面我就说明一下“访问量超过1000的人数”统计案例的实现。
需求
ES在使用过程中,我们公司有一个需求,就是需要统计活跃用户数,我们定义活跃用户数为:今日访问量超过1000的用户,所以我们统计活跃用户数的时候需要统计“访问量超过1000的人数”。
之前的做法
第一版统计活跃用户数的方法由于对复杂的聚合统计不熟悉的原因,就把统计分为了两步。 第一步:在ES中使用字段聚合每个用户的访问数量,数量大于1000;
查询语句
{
"aggs": {
"user": {
"terms": {
"field": "userId.keyword",
"size": 10000,
"order": {
"_count": "desc"
},
"min_doc_count": "1000"
}
}
},
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"startTime": {
"gte": "now-4h",
"lte": "now",
"format": "epoch_millis"
}
}
}
]
}
}
}
查询结果
{
"took" : 203,
"timed_out" : false,
"_shards" : {
"total" : 1565,
"successful" : 1565,
"skipped" : 1520,
"failed" : 0
},
"hits" : {
"total" : 67470,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"user" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "admin",
"doc_count" : 46998
},
{
"key" : "nameless",
"doc_count" : 8416
},
{
"key" : "li",
"doc_count" : 2486
},
{
"key" : "liu",
"doc_count" : 2183
},
{
"key" : "111111",
"doc_count" : 1281
}
]
}
}
}
第二步:从ES中获取第一步的统计结果,然后统计用户桶的个数,达到统计出个数的效果。
改进后的做法
改进后就是直接使用ES的查询,使用了sum_bucket聚合,是计算每个用户的用户ID独立数,也就是每个用户的用户ID独立数都是1,然后用桶聚合求和,得到所有的人数。 参考链接:[sum bucket聚合](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-pipeline-sum-bucket-aggregation.html)
查询语句
{
"aggs": {
"usercount": {
"sum_bucket": {
"buckets_path": "usercount-bucket>usercount-metric"
}
},
"usercount-bucket": {
"terms": {
"field": "userId.keyword",
"size": 10,
"order": {
"_key": "desc"
},
"min_doc_count": "1000"
},
"aggs": {
"usercount-metric": {
"cardinality": {
"field": "userId.keyword"
}
}
}
}
},
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"x_st": {
"gte": "now-4h",
"lte": "now",
"format": "epoch_millis"
}
}
}
]
}
}
}
查询结果
{
"took" : 106,
"timed_out" : false,
"_shards" : {
"total" : 1565,
"successful" : 1565,
"skipped" : 1520,
"failed" : 0
},
"hits" : {
"total" : 63956,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"usercount-bucket" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "nameless",
"doc_count" : 8278,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "liu",
"doc_count" : 2142,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "li",
"doc_count" : 1928,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "admin",
"doc_count" : 44395,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "111111",
"doc_count" : 1281,
"usercount-metric" : {
"value" : 1
}
}
]
},
"usercount" : {
"value" : 5.0
}
}
}
关于sum bucket 与Filter Aggregation 结合的写法分享
Elasticsearch • cq1988114 发表了文章 • 0 个评论 • 3015 次浏览 • 2019-09-19 00:14
"query": {
"query": {
"bool": {
"filter": {
"bool": {
"must": [
{
"term": {
"delflag": 0
}
},
{
"term": {
"is_child": 1
}
}
],
"must_not":
}
}
}
},
"aggs": {
"valid_sales_people": {
"filter": {
"bool": {
"must_not": {
"terms": {
"status": [
0,
1,
7
]
}
}
}
},
"aggs": {
"render_people": {
"terms": {
"field": "uid",
"size": 2147483647
},
"aggs": {
"unique_people": {
"cardinality": {
"field": "uid"
}
}
}
},
"member_count": {
"sum_bucket": {
"buckets_path": "render_people>unique_people"
}
}
}
}
}
},
如代码所示,我希望对status not in (0,1,7)的uid(用户)进行聚合,并想得到uid桶种类的求和,那么member_count就应该与render_people同级,而不是把member_count放到和与valid_sales_people同一级。
如果将member_count 与valid_sales_people放到同一级,会报一个错:sum_bucket的第一个聚合必须是多桶聚合。究其原因,应该是加上filter aggregation后,valid_sales_people已不具有多桶聚合属性(因为附带了filter过滤条件),而其下的render_people则具有了多桶聚合属性。所以member_count应该与render_people放在同级,对应的buckets_path也自然改为render_people>unique_people
记一次“访问量超过1000的人数”统计,计算聚合桶的个数
Elasticsearch • ziyou 发表了文章 • 2 个评论 • 8440 次浏览 • 2019-08-01 18:45
前言
众所周知,在ES中有各种聚合方法能够是数据分析简单、高效。但是在繁杂的聚合方法中找到满足我们需求的那个,需要我们自己去实践。下面我就说明一下“访问量超过1000的人数”统计案例的实现。
需求
ES在使用过程中,我们公司有一个需求,就是需要统计活跃用户数,我们定义活跃用户数为:今日访问量超过1000的用户,所以我们统计活跃用户数的时候需要统计“访问量超过1000的人数”。
之前的做法
第一版统计活跃用户数的方法由于对复杂的聚合统计不熟悉的原因,就把统计分为了两步。 第一步:在ES中使用字段聚合每个用户的访问数量,数量大于1000;
查询语句
{
"aggs": {
"user": {
"terms": {
"field": "userId.keyword",
"size": 10000,
"order": {
"_count": "desc"
},
"min_doc_count": "1000"
}
}
},
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"startTime": {
"gte": "now-4h",
"lte": "now",
"format": "epoch_millis"
}
}
}
]
}
}
}
查询结果
{
"took" : 203,
"timed_out" : false,
"_shards" : {
"total" : 1565,
"successful" : 1565,
"skipped" : 1520,
"failed" : 0
},
"hits" : {
"total" : 67470,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"user" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "admin",
"doc_count" : 46998
},
{
"key" : "nameless",
"doc_count" : 8416
},
{
"key" : "li",
"doc_count" : 2486
},
{
"key" : "liu",
"doc_count" : 2183
},
{
"key" : "111111",
"doc_count" : 1281
}
]
}
}
}
第二步:从ES中获取第一步的统计结果,然后统计用户桶的个数,达到统计出个数的效果。
改进后的做法
改进后就是直接使用ES的查询,使用了sum_bucket聚合,是计算每个用户的用户ID独立数,也就是每个用户的用户ID独立数都是1,然后用桶聚合求和,得到所有的人数。 参考链接:[sum bucket聚合](https://www.elastic.co/guide/en/elasticsearch/reference/6.8/search-aggregations-pipeline-sum-bucket-aggregation.html)
查询语句
{
"aggs": {
"usercount": {
"sum_bucket": {
"buckets_path": "usercount-bucket>usercount-metric"
}
},
"usercount-bucket": {
"terms": {
"field": "userId.keyword",
"size": 10,
"order": {
"_key": "desc"
},
"min_doc_count": "1000"
},
"aggs": {
"usercount-metric": {
"cardinality": {
"field": "userId.keyword"
}
}
}
}
},
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"x_st": {
"gte": "now-4h",
"lte": "now",
"format": "epoch_millis"
}
}
}
]
}
}
}
查询结果
{
"took" : 106,
"timed_out" : false,
"_shards" : {
"total" : 1565,
"successful" : 1565,
"skipped" : 1520,
"failed" : 0
},
"hits" : {
"total" : 63956,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"usercount-bucket" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "nameless",
"doc_count" : 8278,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "liu",
"doc_count" : 2142,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "li",
"doc_count" : 1928,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "admin",
"doc_count" : 44395,
"usercount-metric" : {
"value" : 1
}
},
{
"key" : "111111",
"doc_count" : 1281,
"usercount-metric" : {
"value" : 1
}
}
]
},
"usercount" : {
"value" : 5.0
}
}
}