袁庭新ES系列13节 | 聚合aggregations

前言

上一章节我们带领大家学习了Elasticsearch中的高级查询,这一章节袁老师再带领大家学习一种高级查询:聚合。

聚合可以用来干什么呢?聚合可以让我们极其方便的实现对数据的统计和分析。例如:

  • 什么品牌的手机最受欢迎?
  • 这些手机的平均价格、最高价格、最低价格?
  • 这些手机每月的销售情况如何?

实现这些统计功能的比数据库的SQL要方便的多,而且查询速度非常快,可以实现近实时搜索效果。

一. 基本概念

1.聚合基本概念介绍

Elasticsearch中的聚合,包含多种类型,最常用的两种:一个叫桶,一个叫度量。

桶(bucket)类似于(group by)。桶的作用是,按照某种方式对数据进行分组,每一组数据在Elasticsearch中称为一个桶 ,例如我们根据国籍对人划分,可以得到中国桶、英国桶、日本桶等;或者我们按照年龄段对人进行划分,010岁、10 20岁、2030岁和3040岁等。

Elasticsearch中提供的划分桶的方式有很多:

桶划分方式 描述
Date Histogram Aggregation 根据日期阶梯分组,例如给定阶梯为周,会自动每周分为一组
Histogram Aggregation 根据数值阶梯分组,与日期类似,需要知道分组的间隔(interval)
Terms Aggregation 根据词条内容分组,词条内容完全匹配的为一组
Range Aggregation 数值和日期的范围分组,指定开始和结束,然后按段分组

综上所述,我们发现bucket aggregations只负责对数据进行分组,并不进行计算,因此bucket中往往会嵌套另一种聚合metrics aggregations,即度量。

度量(metrics)相当于聚合的结果。分组完成以后,我们一般会对组中的数据进行聚合运算,例如求平均值、最大、最小、求和等,这些在Elasticsearch中称为度量。

比较常用的一些度量聚合方式:

度量聚合方式 描述
Avg Aggregation 求平均值
Max Aggregation 求最大值
Min Aggregation 求最小值
Percentiles Aggregation 求百分比
Stats Aggregation 同时返回avg、max、min、sum、count等
Sum Aggregation 求和
Top hits Aggregation 求前几
Value Count Aggregation 求总数

2.聚合操作数据准备

为了测试聚合,我们先批量导入一些数据。

创建索引:

bash 复制代码
PUT /car
{
  "mappings": {
    "orders": {
      "properties": {
        "color": {
          "type": "keyword"
        },
        "make": {
          "type": "keyword"
        }
      }
    }
  }
}

响应结果:

注意:在Elasticsearch中,需要进行聚合、排序、过滤的字段其处理方式比较特殊,因此不能被分词,必须使用keyword或数值类型 。这里我们将color和make这两个文字类型的字段设置为keyword类型,这个类型不会被分词,将来就可以参与聚合。

导入数据,这里是采用批处理的API,大家直接复制到Kibana运行即可:

bash 复制代码
POST /car/orders/_bulk
{ "index": {}}
{ "price": 10000, "color": "红", "make": "本田", "sold": "2020-10-28" }
{ "index": {}}
{ "price": 20000, "color": "红", "make": "本田", "sold": "2020-11-05" }
{ "index": {}}
{ "price": 30000, "color": "绿", "make": "福特", "sold": "2020-05-18" }
{ "index": {}}
{ "price": 15000, "color": "蓝", "make": "丰田", "sold": "2020-07-02" }
{ "index": {}}
{ "price": 12000, "color": "绿", "make": "丰田", "sold": "2020-08-19" }
{ "index": {}}
{ "price": 20000, "color": "红", "make": "本田", "sold": "2020-11-05" }
{ "index": {}}
{ "price": 80000, "color": "红", "make": "宝马", "sold": "2020-01-01" }
{ "index": {}}
{ "price": 25000, "color": "蓝", "make": "福特", "sold": "2020-02-12" }

运行上述代码,响应结果:

二. 聚合为桶

1.聚合为桶语法介绍

首先,我们按照汽车的颜色color来划分桶,按照颜色分桶最好是使用Term Aggregation类型,按照颜色的名称来分桶。语法格式见下:

bash 复制代码
GET /索引库名称/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "度量聚合方式": {
        "field": "字段名称"
      }
    }
  }
}

桶查询的相关属性介绍:

属性 描述
size 查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率
aggs 声明这是一个聚合查询,是aggregations的缩写
popular_colors 给这次聚合起一个名字,可任意指定(建议做到见名知意)
terms 聚合的类型,这里选择terms,是根据词条内容(这里是颜色)划分
field 划分桶时依赖的字段

2.聚合为桶案例演示

根据汽车的颜色聚合为桶:

bash 复制代码
GET /car/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      }
    }
  }
}

运行上述代码,响应结果:

json 复制代码
{
  "took": 93,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "popular_colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "红",
          "doc_count": 4
        },
        {
          "key": "绿",
          "doc_count": 2
        },
        {
          "key": "蓝",
          "doc_count": 2
        }
      ]
    }
  }
}

输入的结果如下图所示:

桶查询响应结果的相关属性介绍:

属性 描述
hits 查询结果为空,因为我们设置了size为0
aggregations 聚合的结果
popular_colors 我们定义的聚合名称
buckets 查找到的桶,每个不同的color字段值都会形成一个桶
key 这个桶对应的color字段的值
doc_count 这个桶中的文档数量

通过聚合的结果我们发现,目前红色的小车比较畅销。

三. 桶内度量

1.桶内度量介绍

前面的例子告诉我们每个桶里面的文档数量,这很有用。 但通常,我们的应用需要提供更复杂的文档度量。 例如,每种颜色汽车的平均价格是多少?

因此,我们需要告诉Elasticsearch使用哪个字段,使用何种度量方式进行运算,这些信息要嵌套在桶内,度量的运算会基于桶内的文档进行。

桶内度量语法介绍:

bash 复制代码
GET /索引库名称/_search
{
  "size": 0,
  "aggs": {
    "聚合名称": {
      "度量聚合方式": {
        "field": "字段名称"
      },
      "aggs": {
        "聚合名称": {
          "度量类型": {
            "field": "字段名称"
          }
        }
      }
    }
  }
}

2.桶内度量案例

现在,我们为刚刚的聚合结果添加求价格平均值的度量。

bash 复制代码
GET /car/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      },
      "aggs": {
        "avg_price": {
          "avg": {
            "field": "price"
          }
        }
      }
    }
  }
}

桶内度量相关属性介绍:

属性 描述
aggs 我们在上一个aggs(popular_colors)中添加新的aggs。可见度量也是一个聚合
avg_price 聚合的名称
avg 度量的类型,这里是求平均值
field 度量运算的字段

响应结果:

json 复制代码
{
  "took": 43,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": 8,
    "max_score": 0,
    "hits": []
  },
  "aggregations": {
    "popular_colors": {
      "doc_count_error_upper_bound": 0,
      "sum_other_doc_count": 0,
      "buckets": [
        {
          "key": "红",
          "doc_count": 4,
          "avg_price": {
            "value": 32500
          }
        },
        {
          "key": "绿",
          "doc_count": 2,
          "avg_price": {
            "value": 21000
          }
        },
        {
          "key": "蓝",
          "doc_count": 2,
          "avg_price": {
            "value": 20000
          }
        }
      ]
    }
  }
}

可以看到每个桶中都有自己的avg_price字段,这是度量聚合的结果。

四. 结语

好了关于Elasticsearch中的聚合aggregations查询相关的内容袁老师就给大家介绍到这里,这一章节我们主要学习了聚合的基本概念,例如桶和度量。然后,带领大家通过综合案例的形式学习了如何聚合为桶,以及如何在桶内进行度量操作。关于Elasticsearch的聚合相关内容我们就给大家介绍到这里。下一小节我们带领同学们学习如何使用Elasticsearch进行集群相关的知识。

今天的内容就分享到这里吧。关注「袁庭新」,干货天天都不断!

相关推荐
hycccccch22 分钟前
Springcache+xxljob实现定时刷新缓存
java·后端·spring·缓存
你的人类朋友1 小时前
MQTT协议是用来做什么的?此协议常用的概念有哪些?
javascript·后端·node.js
于过1 小时前
Spring注解编程模型
java·后端
霍徵琅1 小时前
Groovy语言的物联网
开发语言·后端·golang
uhakadotcom2 小时前
阿里云Tea OpenAPI:简化Java与阿里云服务交互
后端·面试·github
申雪菱2 小时前
Scheme语言的数据挖掘
开发语言·后端·golang
程序员一诺2 小时前
【Flask开发】嘿马文学web完整flask项目第1篇:简介【附代码文档】
后端·python·flask·框架
Bruce_Liuxiaowei2 小时前
基于Flask的MBA考生成绩查询系统设计与实现
后端·python·flask
欧宸雅2 小时前
HTML语言的空值合并
开发语言·后端·golang
方瑾瑜3 小时前
Visual Basic语言的物联网
开发语言·后端·golang