elk笔记16--aggs-Bucket Aggregations

本文对聚合中的bucket类型聚合进行进一步介绍,包括基础概念、常见aggs案例、注意事项等部分,后续将在此模块持续补充完善bucket类型的aggs。

1 Bucketing 简介

在桶聚合中,一组聚合构成了多个桶,每个桶与一个关键字、一个文档规则相关联。当一个聚合被执行后,所有的桶规则都会对每一文档进行评估,如果匹配到了某个规则,该文档就会被放到对应桶中。聚合完成后,将会得到一组桶,每个桶里面都会有属于它的文档集。

Bucket 聚合并不会想指标聚合一样在字段上计算属性,它只创建很多文档的桶。每个bucket与一个规则相关联,该规则决定了一个文档是否在某个桶中。换句话说,buckets很高效地定义了文档集合。除了buckets自己外,bucket聚合也计算并返回bucket的文档数量。

与指标聚合相反,bucket聚合可以包含子聚合。子聚合根据其父bucket聚合的bucket文档,可以进一步聚合出一系列文档集合。

es 中有很多不同类型的bucket聚合,每一个都有不同的桶策略。一些定义了单个bucket,一些定义了固定数量的多buckets,还有一些bucket聚合在聚合过程中动态创建buckets。

需要注意的是:es中单次返回的最大桶数量默认为10000,该值可以通过集群参数search.max_buckets来设置,如果返回的桶数量超过该值就会报错。

2 Bucket Aggregations 分类

2.1 Terms Aggregation

terms 聚合即为按照某个字段聚合,例如按照客户聚合,则相同客户所有的订单将构成一个bucket;

GET kibana_sample_data_ecommerce/_search
{
  "aggs": {
    "group_by_user": {
      "terms": {
        "field": "user",
        "size": 2
      }
    }
  },
  "size": 0
}
输出:
{
  "took" : 3,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 10000,
      "relation" : "gte"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "group_by_user" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 12417,
      "buckets" : [
        {
          "key" : "elyssa",
          "doc_count" : 1044
        },
        {
          "key" : "abd",
          "doc_count" : 564
        }
      ]
    }
  }
}

此处最外层size为0的时候将不返回匹配到数据的信息;
field同层的size为2,表示返回订单数量最多的2个用户的数据;
注意:当terms中设置了size后,aggs->terms 获取的数据不一定是准确,因为terms只获取每个shard中的top size个记录,然后对获取的记录进行聚合,而不是对所有的字段聚合后再全局排序。
假如有3个shard, user的size为2,shard中可以统计不同用户购物次数,a1[50] 表示a1 在shard中出现了50次购物记录;

shard Ashard Bshard C
a1[50], a2[40]b1[51], b2[41]c1[52], c2.[42]
d[30]d[30]e[20]

由于size为2,所以每个shard只返回其top2 的数据,即为此次返回a1,a2,b1,b2,c1,c2,再对它们进行排序得到b1和c1 2个记录;理论上shard A 和shard B中d的总次数为60为全局最大,但是由于es的计算方式,导致d并未被返回,因此出现了不准确的现象。
针对这个问题,我们可以通过提高size的值来提高准确性,但是size过大会导致较大的计算量和资源开销,会影响性能。
因此,在实际业务中我们需要综合考虑准确性和查询性能,按照需求加以平衡即可。

2.2 Global aggregators

Global aggregators 对所有搜索上下文的文档定义了一个单bucket, 该文档是有搜索的索引和文档类型决定的,而不受查询条件影响。
Global aggregators 只能放在最上层聚合中,若将其放在另外一个bucket聚合中就有些不合理。
案例:分别计算所有订单的平均交易额和elyssa订单的平均交易额
1)query 过滤出elyssa
2)aggs ->avg 获取elyssa的订单平均金额
3)aggs ->global{},aggs->avg 计算全局订单平均金额

GET kibana_sample_data_ecommerce/_search?size=0
{
  "query": {
    "term": {
      "user": {
        "value": "elyssa"
      }
    }
  },
  "aggs": {
    "all_avg_order_money": {
      "global": {}, 
      "aggs": {
        "avg_money":{
          "avg": {
            "field": "taxful_total_price"
          }
        }
      }
    },
    "elyssa_avg_order_money":{
      "avg": {
        "field": "taxful_total_price"
      }
    }
  }
}
注:global必须放在最外层,golbal这一层加个aggs的avg就可以继续计算全局数据的平均值了
输出:
{
  ...
  "aggregations" : {
    "elyssa_avg_order_money" : {
      "value" : 88.46978268678161
    },
    "all_avg_order_money" : {
      "doc_count" : 14025,
      "avg_money" : {
        "value" : 75.05542864304813
      }
    }
  }
}

2.3 Histogram Aggregation

Histogram Aggregation 属于多bucket类型的聚合,它可以对数值字段按照固定的间隔聚合, 其bucket_key 计算方法如下:
bucket_key = Math.floor((value - offset) / interval) * interval + offset

kibana_sample_data_ecommerce/_search?size=0
{
  "aggs": {
    "range_price": {
      "histogram": {
        "field": "products.price",
        "interval": 50,
        "min_doc_count": 1,
        "keyed": true,
        "extended_bounds": {
          "min": 0,
          "max": 500
        }
      }
    }
  }
}
min_doc_count 默认为0,即某个范围内bucket为空也会生成一个bucket;设置为1后,至少匹配到1个文档后才产生一个bucket;
keyed 默认为false,数据都保存在buckets的数组中;设置为true后,数据存在在对应的buckets的json对象中,每个bucket的key的值即为上述方法计算的buckek_key;
extended_bounds 默认不存在,设置后值会匹配min-max之间的数据;
此外还可以设置missing的数值;;

2.4 Date Histogram Aggregation

Date Histogram Aggregation属于多bucket类型的聚合,它可以对时间字段按照固定的间隔聚合。

GET kibana_sample_data_ecommerce/_search?size=0
{
  "aggs": {
    "range_order_time": {
      "date_histogram": {
        "field": "order_date",
        "calendar_interval": "1q"
      }
    }
  }
}
间隔有3种,分别为calendar_interval,fixed_interval,interval
calendar_interval: 与日历相关的间隔,因此按照月份的话会存在不同月份天数不同,其单位只能为单倍的时间单位,立即ms,s,m,d,M,q,y等;
fixed_interval: 做为对照,通常是多倍的时间单位,如1m,2h,3d等,由于是固定的间隔,而月年等单位天数不是固定的,因此不可以使用,即fixed模式最大的单位为d;
interval: 容易造成歧义,后续将会被弃用,此处不解释;

2.5 Date Range Aggregation

该聚合是专用于时间字段的范围聚合,每个聚合内包含from值所在的数据,不包含to值所在的数据。

GET kibana_sample_data_ecommerce/_search?size=0
{
  "aggs": {
    "range_order_time": {
      "date_range": {
        "field": "order_date",
        "format": "dd-MM-yyy", 
        "time_zone": "CET",
        "ranges": [
          {"from": "now-2d","to": "now-1d"},
          {"to":"now-2d"},
          {"from": "now"}
        ]
      }
    }
  }
}
该聚合也可以使用如下属性:
keyed,
missing

2.6 Range Aggregation

与date_range 相对,该聚合对数值类型字段按照范围就行聚合,且可以接受脚本参数。

GET kibana_sample_data_ecommerce/_search?size=0
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "taxful_total_price",
        "ranges": [
          {"from": "100","to":"200"},
          {"to":"100"},
          {"from": "200"}
        ]
      }
    }
  }
}
也可以将filed改为脚本参数:
"script": {
          "lang": "painless",
          "source": "doc.taxful_total_price.value"
        },

待补充

3 注意事项

to add

4 说明

测试环境:es 7.2.1
7.2/search-aggregations
es 权威指南:aggs-high-level

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

昕光xg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值