在Mysql中,我们可以获取一组数据的 最大值(Max)最小值(Min)。同样我们能够对这组数据进行 分组(Group)。那么对于Elasticsearch中

我们也可以实现同样的功能,聚合有关资料官方文档内容较多,这里大概分两篇博客写这个有关Elasticsearch聚合。

官方对聚合有四个关键字: Metric(指标)Bucketing(桶)Matrix(矩阵)Pipeline(管道)

1.ES聚合分析是什么

Elasticsearch除全文检索功能外提供的针对Elasticsearch数据做统计分析的功能。它的实时性高,所有的计算结果都是即时返回。
Elasticsearch将聚合分析主要分为如下4类:

 Metric(指标):   指标分析类型,如计算最大值、最小值、平均值等等 (对桶内的文档进行聚合分析的操作)
Bucket(桶):     分桶类型,类似SQL中的GROUP BY语法 (满足特定条件的文档的集合)
Pipeline(管道): 管道分析类型,基于上一级的聚合分析结果进行在分析
Matrix(矩阵):   矩阵分析类型(聚合是一种面向数值型的聚合,用于计算一组文档字段中的统计信息)

2.ES聚合分析语法 (aggregations 也可简写为 aggs)

"aggregations" : {
    "<aggregation_name>" : {                                 <!--聚合的名字 -->
        "<aggregation_type>" : {                               <!--聚合的类型 -->
            <aggregation_body>                                 <!--聚合体:对哪些字段进行聚合 -->
        }
        [,"meta" : {  [<meta_data_body>] } ]?               <!--元 -->
        [,"aggregations" : { [<sub_aggregation>]+ } ]?   <!--在聚合里面在定义子聚合 -->
    }
    [,"<aggregation_name_2>" : { ... } ]*                     <!--聚合的名字 -->
}

3、指标(metric)和 桶(bucket)

虽然Elasticsearch有四种聚合方式,但在一般实际开发中,用到的比较多的就是Metric和Bucket。

(1) 桶(bucket)  

  a、简单来说桶就是满足特定条件的文档的集合。

  b、当聚合开始被执行,每个文档里面的值通过计算来决定符合哪个桶的条件,如果匹配到,文档将放入相应的桶并接着开始聚合操作。

  c、桶也可以被嵌套在其他桶里面。

(2)指标(metric)

  a、桶能让我们划分文档到有意义的集合,但是最终我们需要的是对这些桶内的文档进行一些指标的计算。分桶是一种达到目的地的手段:它提供了一种给文档分组的方法来让

我们可以计算感兴趣的指标。

  b、大多数指标是简单的数学运算(如:最小值、平均值、最大值、汇总),这些是通过文档的值来计算的。

 4.指标(metric)详解

 1、单值分析,只输出一个分析结果
min,max,avg,sum,cardinality
2、多值分析,输出多个分析结果
stats,extended_stats,percentile,percentile_rank,top hits
 

5.举例说明 

    1.创建索引并导入数据

PUT /cars/
{
   "mappings" : {
      "properties" : {
        "color" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "make" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "price" : {
          "type" : "long"
        },
        "sold" : {
          "type" : "date"
        }
      }
    }
  
}
POST /cars/_bulk
{ "index": {}}
{ "price" : 10000, "color" : "red", "make" : "honda", "sold" : "2014-10-28" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 30000, "color" : "green", "make" : "ford", "sold" : "2014-05-18" }
{ "index": {}}
{ "price" : 15000, "color" : "blue", "make" : "toyota", "sold" : "2014-07-02" }
{ "index": {}}
{ "price" : 12000, "color" : "green", "make" : "toyota", "sold" : "2014-08-19" }
{ "index": {}}
{ "price" : 20000, "color" : "red", "make" : "honda", "sold" : "2014-11-05" }
{ "index": {}}
{ "price" : 80000, "color" : "red", "make" : "bmw", "sold" : "2014-01-01" }
{ "index": {}}
{ "price" : 25000, "color" : "blue", "make" : "ford", "sold" : "2014-02-12" }

   2.找到价格最高和最低的车辆

GET /cars/_search
{
  "size":0,
  "aggs": {
    "min_price":{
      "min":{
        "field": "price"
      }
    },
    "max_price":{
       "max":{
        "field": "price"
      }
    },
    "avg_price":{
      "avg": {
        "field": "price"
      }
    }
  }
  
}

 3.查看车辆颜色总共几种类型  

GET /cars/_search
{
  "size":0,
  "aggs": {
    "count":{
      "cardinality":{
        "field":"color.keyword"
      }
    }
  }
}

  4.获取每种颜色车辆最高价格,平均价格,最低价格

GET /cars/_search
{
  "size":0,
  "aggs": {
    "stat_by_color":{
      "terms": {
        "field": "color.keyword"
      },
      "aggs": {
        "max_price":{
          "max":{"field":"price"}
        },
        "avg_price":{
          "avg": {
            "field": "price"
          }
        },
         "min_price":{
            "min":{
              "field":"price"
            }
          }
      }
    }
  }
}

   5.查看中位数车辆的价格

GET /cars/_search
{

    "size": 0,
    "aggs": {
        "load_time_outlier": {
            "percentiles": {
                "field": "price",
                 "percents" : [50,80,99],
                "keyed": false
            }
        }
    }
}

field必须是数字类型)

GET /cars/_search
{
  "size":0,
  "aggs": {
    "info":{
      "stats":{
        "field":"price"
      }
    }
  }
}

7.过滤后聚合

如果我们想找到售价在 $10,000 美元之上的所有汽车同时也为这些车计算平均售价, 可以简单地使用一个 constant_score 查询和 filter 约束:

GET /cars/_search
{
    "size" : 0,
    "query" : {
        "constant_score": {
            "filter": {
                "range": {
                    "price": {
                        "gte": 10000
                    }
                }
            }
        }
    },
    "aggs" : {
        "single_avg_price": {
            "avg" : { "field" : "price" }
        }
    }
}