TypechoJoeTheme

IT技术分享

统计

08. ES分桶聚合查询——ElasticSerach搜索专栏

2022-06-16
/
0 评论
/
796 阅读
/
正在检测是否收录...
06/16

Elasticsearch中的桶在概念上类似于SQL的分组(GROUP BY),而聚合桶中的指标则类似于COUNT()、SUM()、MAX()等统计方法

一、简单的聚合

GET /dbindex/_search
{
    "size" : 0, // 表示只要统计后的结果,原始数据不需要返回,如果是大于0的,则会返回对应数量的文档数据。
    "aggs" : {  // 固定语法,聚合分析都要声明aggs或者aggregations。
        "popular_colors" : { // 聚合的名称,可以随便命名,但建议规范命名
            "terms" : {      // 表示按哪个字段进行分组
              "field" : "color.keyword" // 表示具体的字段名称
            }
        }
    }
}

返回结果

{
  "aggregations" : {
    "popular_colors" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "red",
          "doc_count" : 3
        },
        {
          "key" : "green",
          "doc_count" : 2
        },
        {
          "key" : "blue",
          "doc_count" : 1
        }
      ]
    }
  }
}

二、多个聚合

GET /dbindex/_search
{
    "size" : 0,
    "aggs" : {
        "popular_colors" : {
            "terms" : {
              "field" : "color.keyword"
            }
        },
        "popular_make" : {
            "terms" : {
              "field" : "make.keyword"
            }
        }
    }
}

返回结果

{
  "aggregations" : {
    "popular_make" : {   // 厂商字段聚合统计结果
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "honda",
          "doc_count" : 2
        },
        {
          "key" : "toyota",
          "doc_count" : 2
        },
        {
          "key" : "bmw",
          "doc_count" : 1
        },
        {
          "key" : "ford",
          "doc_count" : 1
        }
      ]
    },
    "popular_colors" : {  // 颜色聚合结果
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "red",
          "doc_count" : 3
        },
        {
          "key" : "green",
          "doc_count" : 2
        },
        {
          "key" : "blue",
          "doc_count" : 1
        }
      ]
    }
  }
}

三、动态脚本聚合

Elasticsearch还支持一些基于脚本(生成运行时的字段)的复杂动态聚合

GET /dbindex/_search
{
  "runtime_mappings": {
    "make_content_length": {
      "type": "long",
      "script": "emit(doc['make.keyword'].value.length())" // 运行时脚本计算make字段内容的长度
    }
  },
  "size" : 0,
  "aggs": {
    "make_length": {
      "histogram": {
        "interval": 1,
        "field": "make_content_length" // 根据运行时make字段的内容长度进行聚合统计
      }
    }
  }
}

返回结果

{
  "aggregations" : {
    "make_length" : {
      "buckets" : [
        {
          "key" : 3.0,                  // 表示厂商名称的长度
          "doc_count" : 1               // 厂商名称长度等于3的文档数量
        },
        {
          "key" : 4.0,                  // 表示厂商名称的长度
          "doc_count" : 1
        },
        {
          "key" : 5.0,                  // 表示厂商名称的长度
          "doc_count" : 2
        },
        {
          "key" : 6.0,                  // 表示厂商名称的长度
          "doc_count" : 2
        }
      ]
    }
  }
}

四、过滤聚合

在SQL中,我们经常会先进行筛选,再进行聚合统计。Elasticsearch中也支持先筛选再聚合

举例:聚合计算厂商toyota出售车的平均价格和出售的总数量

GET /dbindex/_search
{
  "size": 0,
  "aggs": {
    "make_by": {
      "filter": { "term": { "make": "toyota" } },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } }
      }
    }
  }
}

返回结果

{
  "hits" : {
    "total" : {
      "value" : 6,
      "relation" : "eq"
    },
    "max_score" : null,
    "hits" : [ ]
  },
  "aggregations" : {
    "make_by" : {
      "doc_count" : 2,
      "avg_price" : {
        "value" : 15500.0
      }
    }
  }
}

五、filter分组聚合

GET /dbindex/_search
{
  "size": 0,
  "aggs" : {
    "messages" : {
      "filters" : {
        "other_bucket_key": "other_color",
        "filters" : {
          "reds" :   { "match" : { "color" : "red"   }},
          "greens" : { "match" : { "color" : "green" }}
        }
      }
    }
  }
}

返回结果

{
  "aggregations" : {
    "messages" : {
      "buckets" : {
        "greens" : {
          "doc_count" : 2 // 绿色车辆的数量
        },
        "reds" : {
          "doc_count" : 3 // 红色车辆的颜色
        },
        "other_color" : {
          "doc_count" : 1 // 其他车辆的颜色
        }
      }
    }
  }
}

六、数值范围聚合

Elasticsearch提供了基于多桶值源的聚合方式。通过这种方式可以定义一组范围,每个范围代表一个桶

GET /dbindex/_search
{
  "size": 0,
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [   // 如下是一组范围条件
          { "to": 10000 },
          { "from": 10000, "to": 20000 },
          { "from": 20000, "to": 30000 },
          { "from": 40000 }
        ]
      }
    }
  }
}

返回结果

{
  "aggregations" : {
    "price_ranges" : {
      "buckets" : [
        {
          "key" : "*-10000.0",          // 0~10000的聚合结果
          "to" : 10000.0,
          "doc_count" : 0
        },
        {
          "key" : "10000.0-20000.0",    // 10000~20000的聚合结果
          "from" : 10000.0,
          "to" : 20000.0,
          "doc_count" : 3
        },
        {
          "key" : "20000.0-30000.0",    // 20000~30000的聚合结果
          "from" : 20000.0,
          "to" : 30000.0,
          "doc_count" : 1
        },
        {
          "key" : "40000.0-*",          // 40000以上的聚合结果
          "from" : 40000.0,
          "doc_count" : 1
        }
      ]
    }
  }
}

七、指定范围间隔聚合

指定范围间隔(Histrogram)来进行聚合统计

举例:聚合统计,根据出售价格范围进行分组,每一组之间价格相差40000

GET /dbindex/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{
            "field": "price",
            "interval": 40000
         }
      }
   }
}

返回结果

{
  "aggregations" : {
    "price" : {
      "buckets" : [
        {
          "key" : 0.0,                  // 0~40000出售价格的聚合
          "doc_count" : 5
        },
        {
          "key" : 40000.0,              // 40000~80000出售价格的聚合
          "doc_count" : 0
        },
        {
          "key" : 80000.0,              // 80000以上出售价格的聚合
          "doc_count" : 1
        }
      ]
    }
  }
}

如果还想知道每一种价格区间的最高出售价格、最低出售价格和平均出售价格

GET /dbindex/_search
{
   "size" : 0,
   "aggs":{
      "price":{
         "histogram":{
            "field": "price",
            "interval": 40000
         } ,
       "aggs": {
        "stats": {
          "extended_stats": {
            "field": "price"
          }
        }
      }
      }
   }
}

返回结果

{
    "aggregations":{
        "price":{
            "buckets":[
                {
                    "key":0,
                    "doc_count":5,
                    "stats":{
                        "count":5,
                        "min":10000,
                        "max":30000,
                        "avg":18200,
                        "sum":91000,
                        "sum_of_squares":1881000000,
                        "variance":44960000,
                        "variance_population":44960000,
                        "variance_sampling":56200000
                    }
                },
                {
                    "key":80000,
                    "doc_count":1,
                    "stats":{
                        "count":1,
                        "min":80000,
                        "max":80000,
                        "avg":80000,
                        "sum":80000
                    }
                }
            ]
        }
    }
}

八、日期范围聚合

GET /dbindex/_search
{
  "size": 0,
  "aggs": {
    "range": {
      "date_range": {
        "field": "soldtime",
        "format": "yyyy-MM-dd",
        "ranges": [
          { "from": "2021-06-30" },
          { "to": "2021-07-01" }
        ]
      }
    }
  }
}

返回结果

{
  "aggregations" : {
    "range" : {
      "buckets" : [
        {
          "key" : "*-2021-07-01",
          "to" : 1.6250976E12,
          "to_as_string" : "2021-07-01",
          "doc_count" : 3
        },
        {
          "key" : "2021-06-30-*",
          "from" : 1.6250112E12,
          "from_as_string" : "2021-06-30",
          "doc_count" : 3
        }
      ]
    }
  }
}

日期范围统计还支持根据"Date Math"表达式进行范围分解统计

举例:计算5个月之前和之后的销售车辆数量

GET /dbindex/_search
{
  "size": 0,
  "aggs": {
    "range": {
      "date_range": {
        "field": "soldtime",
        "format": "yyyy-MM-dd",
        "ranges": [
          { "from": "now-5M/M" },
          { "to": "now-5M/M" }
        ]
      }
    }
  }
}

返回结果

{
  "aggregations" : {
    "range" : {
      "buckets" : [
        {
          "key" : "*-2021-02-01",               // 2021-02-01之前的销售数量
          "to" : 1.6121376E12,
          "to_as_string" : "2021-02-01",
          "doc_count" : 2
        },
        {
          "key" : "2021-02-01-*",               // 2021-02-01之后的销售数量
          "from" : 1.6121376E12,
          "from_as_string" : "2021-02-01",
          "doc_count" : 4
        }
      ]
    }
  }
}
朗读
赞 · 0
版权属于:

IT技术分享

本文链接:

https://idunso.com/archives/2883/(转载时请注明本文出处及文章链接)