ES聚合查询

1.ES聚合查询流程

ES的聚合查询类似于SQL的GROUP BY,一般查询过程分为两个步骤:

  1. 分组
  2. 组内聚合

分组:对查询的数据首先进行一轮分组,可以设置分组条件,例如:新生入学,把所有的学生按专业分班,这个分班的过程就是对学生进行了分组。

组内聚合:即对组内的数据进行统计,例如:计算总数、求平均值等等,接上面的例子,学生都按专业分班了,那么就可以统计每个班的学生总数, 这个统计每个班学生总数的计算,就是组内聚合计算。

2.相关概念

1)桶满足特定条件的文档的集合ES使用桶代表一组相同特征的数据。对数据分组后,得到一组组的数据,就是一个个的桶。

2)指标对文档进行统计计算方式,又叫指标聚合桶内聚合,先对数据进行分组(分桶),然后对每一个桶内的数据进行指标聚合。常用指标有COUNT、SUM、AVG、MAX、MIN。

3.ES聚合查询语法

{
  "aggregations" : {
    "<aggregation_name>" : {
        "<aggregation_type>" : {
            <aggregation_body>
        }
        [,"aggregations" : { [<sub_aggregation>]+ } ]? // 嵌套聚合查询,支持多层嵌套
    }
    [,"<aggregation_name_2>" : { ... } ]* // 多个聚合查询,每个聚合查询取不同的名字
  }
}
  • aggregations - 代表聚合查询语句,可以简写为aggs
  • <aggregation_name> - 代表一个聚合计算的名字,可以随意命名,因为ES支持一次进行多次统计分析查询,后面需要通过这个名字在查询结果中找到我们想要的计算结果。
  • <aggregation_type> - 聚合类型,代表我们想要怎么统计数据,主要有两大类聚合类型,桶聚合和指标聚合,这两类聚合又包括多种聚合类型,例如:指标聚合:sum、avg桶聚合:terms、Date histogram等等。
  • <aggregation_body> - 聚合类型的参数,选择不同的聚合类型,有不同的参数。
  • aggregation_name_2 - 代表其他聚合计算的名字,意思就是可以一次进行多种类型的统计。
  1. 指标聚合:

ES指标聚合,就是类似SQL的统计函数,指标聚合可以单独使用,也可以跟桶聚合一起使用。

  • Value Count - 类似sql的count函数,统计总数
  • Cardinality - 类似SQL的count(DISTINCT 字段), 统计不重复的数据总数
  • Avg - 求平均值
  • Sum - 求和
  • Max - 求最大值
  • Min - 求最小值
  • Percentiles - 用于百分位统计
GET /sales/_search?size=0
{
  "aggs": {
    "types_count": { // 聚合查询的名字
      "value_count": { // 聚合类型为:value_count
        "field": "type" // 计算type这个字段值的总数
      }
    }
  }
}

POST /sales/_search?size=0
{
    "aggs" : {
        "type_count" : { // 聚合查询的名字,随便取一个
            "cardinality" : { // 聚合查询类型为:cardinality,统计不重复数据总数
                "field" : "type" // 根据type这个字段统计文档总数
            }
        }
    }
}
GET latency/_search
{
  "size": 0,
  "aggs" : {
    "load_time_outlier" : {
      "percentiles" : {
        "field" : "load_time" //按照字段数值排序,统计各百分比内的数据量
      }
    }
  }
}

2)分桶聚合Elasticsearch桶聚合,目的就是数据分组,先将数据按指定的条件分成多个组,然后对每一个组进行统计。

ES桶聚合的作用跟SQL的group by的作用是一样的,区别是ES支持更加强大的数据分组能力,SQL只能根据字段的唯一值进行分组,分组的数量跟字段的唯一值的数量相等, ES常用的桶聚合如下:

  • Terms聚合 - 类似SQL的group by,根据字段唯一值分组
  • Histogram聚合 - 根据数值间隔分组,例如:按100间隔分组,0、100、200、300等等
  • Date histogram聚合 - 根据时间间隔分组,例如:按月、按天、按小时分组
  • Range聚合 - 按数值范围分组,例如: 0-150一组,150-200一组,200-500一组。

桶聚合一般不单独使用,都是配合指标聚合一起使用,对数据分组之后肯定要统计桶内数据,在ES中如果没有明确指定指标聚合,默认使用Value Count指标聚合,统计桶内文档总数。

terms聚合:根据字段值项分组聚合

GET /order/_search
{
    "size" : 0,  // 设置size=0的意思就是,仅返回聚合查询结果
    "aggs" : {  // 聚合查询语句的简写
        "popular_colors" : {  // 给聚合查询取的名字
              "terms" : {  // 聚合类型为,terms,根据字段分组,              
                    "field" : "color" //聚合类型的参数,需要设置分组的段   
                     }
          }
      }
}

Histogram聚合:主要根据数值间隔分组,使用histogram聚合分桶统计结果,通常用在绘制条形图报表。

POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : { // 聚合查询名字
            "histogram" : { // 聚合类型为:histogram
                "field" : "price", // 根据price字段分桶
                "interval" : 50 // 分桶的间隔为50,意思就是price字段值按50间隔分组
            }
        }
    }
}

Date histogram聚合:类似histogram聚合,区别是Date histogram可以很好的处理时间类型字段,主要用于根据时间、日期分桶的场景。

POST /sales/_search?size=0
{
    "aggs" : {
        "sales_over_time" : { // 聚合查询名字
            "date_histogram" : { // 聚合类型为: date_histogram
                "field" : "date", // 根据date字段分组
                "calendar_interval" : "month", // 分组间隔:month代表每月、支持minute(每分钟)、hour(每小时)、day(每天)、week(每周)、year(每年)
                "format" : "yyyy-MM-dd" // 设置返回结果中桶key的时间格式
            }
        }
    }
}

Range聚合:按数值范围分桶。

GET /_search
{
    "aggs" : {
        "price_ranges" : { // 聚合查询名字
            "range" : { // 聚合类型为: range
                "field" : "price", // 根据price字段分桶
                "ranges" : [ // 范围配置
                    { "to" : 100.0 }, // 意思就是 price <= 100的文档归类到一个桶
                    { "from" : 100.0, "to" : 200.0 },100-200的文档归类到一个桶
                    { "from" : 200.0 } // price>200的文档归类到一个桶
                ]
            }
        }
    }
}

Filter聚合:过滤器聚合,可以把符合过滤器条件的文档分到一个组中,即单分组聚合。

{
  "aggs": {
    "age_terms": {
      "filter": {"match":{"gender":"F"}},
      "aggs": {
        "avg_age": {
          "avg": {
            "field": "age"
          }
        }
      }
    }
  }
}

Filters聚合:多过滤器聚合,可以把符合多个过滤条件的文档分到不同的桶中,即每个桶关联一个过滤条件,并收集符合自身过滤条件的文档。

{
  "size": 0,
  "aggs": {
    "messages": {
      "filters": {
        "filters": {
          "errors": { "match": { "body": "error" } },
          "warnings": { "match": { "body": "warning" } }
        }
      }
    }
  }
}

先搜索目标文档,然后使用aggs聚合语句对搜索结果进行统计分析。

GET /cars/_search
{
    "size": 0, // size=0代表不需要返回query查询结果,仅仅返回aggs统计结果
    "query" : { // 设置查询语句,先筛选文档
        "match" : {
            "make" : "ford"
        }
    },
    "aggs" : { // 然后对query搜索的结果,进行统计
        "colors" : { // 聚合查询名字
            "terms" : { // 聚合类型为:terms 先分桶
              "field" : "color"
            },
            "aggs": { // 通过嵌套聚合查询,设置桶内指标聚合条件
              "avg_price": { // 聚合查询名字
                "avg": { // 聚合类型为: avg指标聚合
                  "field": "price" // 根据price字段计算平均值
                }
              },
              "sum_price": { // 聚合查询名字
                "sum": { // 聚合类型为: sum指标聚合
                  "field": "price" // 根据price字段求和
                }
              }
            }
        }
    }
}

4.聚合后排序

1)内置排序

_count - 按文档数排序。对 terms 、 histogram 、 date_histogram 有效

_term - 按词项的字符串值的字母顺序排序。只在 terms 内使用

_key - 按每个桶的键值数值排序, 仅对 histogram 和 date_histogram 有效

GET /cars/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : { // 聚合查询名字
            "terms" : { // 聚合类型为: terms
              "field" : "color",
              “size” : 5  //限制返回5个桶
              "order": { // 设置排序参数
              "_count" : "asc"  // 根据_count排序,asc升序,desc降序
              }
            }
        }
    }
}
  1. 按度量排序:通常情况下,我们根据桶聚合分桶后,都会对桶内进行多个维度的指标聚合,所以我们也可以根据桶内指标聚合的结果进行排序。
GET /cars/_search
{
    "size" : 0,
    "aggs" : {
        "colors" : { // 聚合查询名字
            "terms" : { // 聚合类型: terms,先分桶
              "field" : "color", // 分桶字段为color
              "order": { // 设置排序参数
                "avg_price" : "asc"  // 根据avg_price指标聚合结果,升序排序。
              }
            },
            "aggs": { // 嵌套聚合查询,设置桶内聚合指标
                "avg_price": { // 聚合查询名字,前面排序引用的就是这个名字
                    "avg": {"field": "price"} // 计算price字段平均值
                }
            }
        }
    }
}

5.管道聚合

1)最大值桶max_bucket

同级管道聚合,获取所有桶中的sum合计指标的最大值

POST /_search
{
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales": {
          "sum": {
            "field": "price"
          }
        }
      }
    },
    "max_monthly_sales": {
      "max_bucket": {
        "buckets_path": "sales_per_month>sales"
      }
    }
  }
}

2)桶排序 bucket_sort

父管道聚合,对其父多桶聚合的桶进行排序。可以将零个或多个排序字段与相应的排序顺序一起指定。每个 bucket 可以根据其_key、_count 或其子聚合进行排序。

此外,可以设置from和size的参数,以截断结果存储桶。

POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_per_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "total_sales": {
          "sum": {
            "field": "price"
          }
        },
        "sales_bucket_sort": {
          "bucket_sort": {
            "sort": [
              { "total_sales": { "order": "desc" } }
            ],
            "size": 3                                
          }
        }
      }
    }
  }
}

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值