ElasticSearch 使用详解:如何根据聚合求取各种数值指
聚合分析是非常重要的一种分析方式,因为只有把相同特征的数据聚合到一起,你才能看到问题的本质。聚合的本质其实就是一个分组的概念,比如说求解某个指标的平均值、极大值、极小值、方差等,都可以使用聚合分析来做。同样你也可以选择把数据都取回来,然后在本地统计,但是你需要考虑到网络的问题,如果数据比较多,就会一直占用 ES 资源,另外一个问题是,你本地内存是否够用、运算时间较长等问题,ES 是分布式的,性能强大,统计需求完全可以放在 ES 来做,然后返回结果。
在前面的课时上,有介绍如何使用 Kibana 做聚合分桶,然后将结果可视化。但是有时候这远远不能满足我们的需求,可能我们需要统计值在其他需求上的支持,或者需要把统计值加上业务逻辑,这个时候就需要把统计值取回来,而不是在 Kibana 上做可视化分析。取是个关键步骤,最关键的还是如何取?DSL 该如何写?
指标聚合
指标来自于文档的某个字段,有的聚合会产生单个值,这个被叫做单值数字指标聚合,像求取平均值的聚合 avg,有的则会产生多个值,被称作多值数据指标聚合,像 stats。聚合的过程也就是分桶的过程,粗浅一点就是 group by 的过程。
根据什么来进行分组数据?
使用 Kibana 自带的电子商务订单索引为案例的数据索引。
sum、avg、min、max
给定需求:
男人在购买不同类别商品上单的平均值是多少?
分析这个需求,首先是要把男人的购买记录筛选出来,然后再根据商品的类别分桶,SQL 里面可以表示为 group by '商品类别'
,在 DSL 里面使用 aggs 关键词来确定一个桶。
在索引管理中找到客户性别 customer_gender 字段,不难发现它的 type 只有 keyword,没有 text。因此在查询的时候,直接使用这个字段不需要使用 customer_gender.keyword 来过滤。
image-首先过滤性别为男性的订单数据,这里没有必要计算 _score 相似度分数,因此使用 filter 计算,首先是定义一个 query,然后再套一个 bool 字段,在 bool 字段里面定义 filter 的 term 精确值查询。因为 customer_gender 只有 keyword 类型,因此直接使用这个字段做精确值查询,size 简单地设置一个数用来做过滤数据验证,判断是否能够正确地过滤出数据。
GET /kibana_sample_data_ecommerce/_search
{
"size": 10,
"query": {
"bool": {
"filter": {
"term": {
"customer_gender": "MALE"
}
}
}
}
}
过滤出数据之后,这些数据就相当于在一个桶里面,这个时候需要对数据进行分桶,根据商品类别进行分桶,然后再对各个桶进行计算价格的平均值。
查询语句如下,利用 aggs 关键字来实现分桶的效果,query 与 aggs 是处于同一个级别的。在 aggs 下面需要先人为定义一个聚合名称,我定义为 category,使用 terms 关键字来实现针对不同类别分桶,字段名称是 category.keyword,size 大小默认是 10,可以根据需求定义大一点。
现在我们得到了根据不同商品类别分组的桶,我们需要在这个桶的基础上在进行值聚合。在 terms 同级下定义一个 aggs,同样定义一个名称 avg,再只用关键字 avg、字段 field 设置为商品价格 taxful_total_price。
POST /kibana_sample_data_ecommerce/_search
{
"size": 0,
"query": {
"bool": {
"filter": {
"term": {
"customer_gender": "MALE"
}
}
}
},"aggs": {
"category": {
"terms": {
"field": "category.keyword",
"size": 10
},"aggs": {
"avg": {
"avg": {
"field": "taxful_total_price"
}
}
}
}
}
}
image-