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

前言

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

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

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

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

一. 基本概念

1.聚合基本概念介绍

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

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

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.聚合操作数据准备

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

创建索引:

PUT /car
{
  "mappings": {
    "orders": {
      "properties": {
        "color": {
          "type": "keyword"
        },
        "make": {
          "type": "keyword"
        }
      }
    }
  }
}

响应结果:

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

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

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类型,按照颜色的名称来分桶。语法格式见下:

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

桶查询的相关属性介绍:

属性

描述

size

查询条数,这里设置为0,因为我们不关心搜索到的数据,只关心聚合结果,提高效率

aggs

声明这是一个聚合查询,是aggregations的缩写

popular_colors

给这次聚合起一个名字,可任意指定(建议做到见名知意)

terms

聚合的类型,这里选择terms,是根据词条内容(这里是颜色)划分

field

划分桶时依赖的字段

2.聚合为桶案例演示

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

GET /car/_search
{
  "size": 0,
  "aggs": {
    "popular_colors": {
      "terms": {
        "field": "color"
      }
    }
  }
}

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

{
  "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使用哪个字段,使用何种度量方式进行运算,这些信息要嵌套在桶内,度量的运算会基于桶内的文档进行。

桶内度量语法介绍:

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

2.桶内度量案例

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

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

度量运算的字段

响应结果:

{
  "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进行集群相关的知识。

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值