前言
我们在使用聚合时总是有各种各样的聚合需求,其中一个比较常用的就是根据聚合的结果过滤聚合的桶,例如:1、每个IP登录次数超过5次的IP;2、每个IP登录人数超过2的IP。 还有我之前的一个案例,访问量超过1000的人数,这些都是很常见的统计需求。
案例需求
我们在使用聚合计算的时候一般都有两类,一种是计算文档的数量,另一种是计算文档内字段的值的数量(去重计算)或者值的数学计算。两种聚合计算在过滤的时候采用不同的方法来计算。
我们使用以下案例来说明两种过滤的不同: 用户每次登录都会记录一个登录记录:
{"userID":"a","IP":"10.70.25.1","time":"2019-10-10 12:12:12.222"}
然后提出以下两个需求: 1、每个IP登录次数超过5次的IP; 2、每个IP登录人数超过2的IP。
实现
每个IP登录次数超过5次的IP
这个是对登录记录个数的桶聚合统计,然后过滤。使用IP做term聚合,就可以得出每个IP的登录次数,然后term聚合中有一个参数min_doc_count这个字段就可以对文档数量进行过滤,具体的语句如下: 查询语句
{
"aggs": {
"IP": {
"terms": {
"field": "IP",
"size": 3000,
"order": {
"_count": "desc"
},
"min_doc_count": 5
}
}
},
"size": 0
}
结果
{
"took" : 614,
"timed_out" : false,
"num_reduce_phases" : 3,
"_shards" : {
"total" : 1105,
"successful" : 1105,
"skipped" : 75,
"failed" : 0
},
"hits" : {
"total" : 2826,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"IP" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "10.25.90.139",
"doc_count" : 61
},
{
"key" : "10.25.78.146",
"doc_count" : 45
},
{
"key" : "10.25.94.22",
"doc_count" : 21
},
{
"key" : "10.25.75.52",
"doc_count" : 18
},
{
"key" : "10.25.89.32",
"doc_count" : 13
},
{
"key" : "10.25.93.243",
"doc_count" : 10
},
{
"key" : "10.25.78.189",
"doc_count" : 9
},
{
"key" : "10.25.90.82",
"doc_count" : 8
},
{
"key" : "10.25.91.240",
"doc_count" : 8
},
{
"key" : "10.25.90.57",
"doc_count" : 7
},
{
"key" : "10.25.91.251",
"doc_count" : 7
},
{
"key" : "10.25.95.166",
"doc_count" : 6
},
{
"key" : "10.25.89.33",
"doc_count" : 5
},
{
"key" : "10.25.90.88",
"doc_count" : 5
},
{
"key" : "10.25.92.53",
"doc_count" : 5
}
]
}
}
}
每个IP登录人数超过2的IP
这个是对登录记录用户ID的去重数聚合,然后过滤。对用户ID进行去重可以使用Cardinality Aggregation聚合,然后再使用Bucket Selector Aggregation聚合过滤器过滤数据。具体内容如下: 查询语句
{
"aggs": {
"IP": {
"terms": {
"field": "IP",
"size": 3000,
"order": {
"distinct": "desc"
},
"min_doc_count": 5
},
"aggs": {
"distinct": {
"cardinality": {
"field": "IP.keyword"
}
},
"dd":{
"bucket_selector": {
"buckets_path": {"userCount":"distinct"},
"script": "params.userCount > 2"
}
}
}
}
},
"size": 0
}
结果
{
"took" : 317,
"timed_out" : false,
"num_reduce_phases" : 3,
"_shards" : {
"total" : 1105,
"successful" : 1105,
"skipped" : 75,
"failed" : 0
},
"hits" : {
"total" : 2826,
"max_score" : 0.0,
"hits" : [ ]
},
"aggregations" : {
"IP" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 0,
"buckets" : [
{
"key" : "10.25.75.52",
"doc_count" : 18,
"distinct" : {
"value" : 4
}
},
{
"key" : "10.25.78.146",
"doc_count" : 45,
"distinct" : {
"value" : 3
}
},
{
"key" : "10.25.90.139",
"doc_count" : 61,
"distinct" : {
"value" : 3
}
},
{
"key" : "10.25.91.240",
"doc_count" : 8,
"distinct" : {
"value" : 3
}
},
{
"key" : "10.25.94.22",
"doc_count" : 21,
"distinct" : {
"value" : 3
}
}
]
}
}
}
[尊重社区原创,转载请保留或注明出处]
本文地址:http://searchkit.cn/article/13501
本文地址:http://searchkit.cn/article/13501
1 个评论
es在6.3之后开始Elasticsearch SQL的功能,这个高级产品特性splunk在很久以上就完善了这个功能并且有大量的搜索关键字和逻辑搜索功能,称之为spl语句,这个也是splunk能够成为商用软件一个很重要的原因。dsl在实现稍微复杂的功能搜索的时候极为复杂,如果多索引数据之间join查询,分桶关联,因此sql功能后续应该会成为主流,后续期待elasticsearch完善更多的功能放在sql access