ElasticSearch-6-聚合操作详解

 
ElasticSearch-6-聚合操作详解

 

1、简介

聚合操作可以用于生成数据的汇总信息,类似于 SQL 中的 GROUP BY 和聚合函数(如 COUNT、SUM、AVG 等)。

聚合主要分为三类:

  1. 指标聚合(Metric Aggregations):用于计算数值,如总和、平均值、最大值等。

  2. 桶聚合(Bucket Aggregations):将文档分配到不同的桶中,类似于分组。

  3. 管道聚合(Pipeline Aggregations):对其他聚合的结果进行再聚合。

聚合语法:

GET <index_name>/_search
{
"size": 0,
"aggs": { "<aggs_name>": { // 聚合名称需要自己定义 "<agg_type>": { "field": "<field_name>" } }, "aggs": { // 子聚合 "agg2_name": { "agg2_type": { ... } } }
  • aggs_name:聚合函数的名称
  • agg_type:聚合种类,比如是桶聚合(terms)或者是指标聚合(avg、sum、min、max等)
  • field_name:字段名称或者叫域名。
  • 使用size参数控制返回的桶数量,特别是在terms聚合中。

2、指标聚合(Metric Aggregations)

指标聚合用于计算文档的数值型字段的统计值。常见的指标聚合有:

  • avg:平均值

  • sum:求和

  • min:最小值

  • max:最大值

  • count:计数

  • stats:同时返回计数、总和、平均值、最小值、最大值

  • extended_stats:除了stats的内容,还返回平方和、方差、标准差等

  • cardinality:去重计数

示例:

{
  "size": 0,
  "aggs": {
    "avg_price": { "avg": { "field": "price" } },            // 平均值
    "max_price": { "max": { "field": "price" } },            // 最大值
    "min_price": { "min": { "field": "price" } },            // 最小值
    "sum_price": { "sum": { "field": "price" } },            // 总和
    "count_products": { "value_count": { "field": "price" } }, // 计数
    "price_cardinality": {
      "cardinality": {  // 去重计数(类似 COUNT DISTINCT)
        "field": "product_id",
        "precision_threshold": 1000  // 精度阈值
      }
    }
  }
}

 

3、桶聚合(Bucket Aggregations)

桶聚合将文档分配到不同的桶中,每个桶对应一个键。常见的桶聚合有:

  • terms:按字段值分组,每个值一个桶

  • range:按数值范围分组

  • date_range:按日期范围分组

  • histogram:直方图,按固定间隔分组

  • date_histogram:按日期间隔分组

  • filter:按过滤条件分组

terms聚合示例(最常用):

{
  "size": 0,
  "aggs": {
    "categories": {
      "terms": {
        "field": "category.keyword",
        "size": 10,                    // 返回桶数量
        "min_doc_count": 2,            // 最小文档数
        "shard_size": 100,             // 每个分片返回数量
        "show_term_doc_count_error": true,  // 显示文档计数误差
        "order": [                     // 排序
          { "_count": "desc" },        // 按文档数降序
          { "_key": "asc" }            // 按键值升序
        ],
        "include": ".*phone.*",        // 包含匹配正则的项
        "exclude": ".*accessory.*"     // 排除匹配正则的项
      },
      "aggs": {
        "avg_price": { "avg": { "field": "price" } }
      }
    }
  }
}
注意:对 Text 字段进行 terms 聚合查询,会失败抛出异常

image

解决办法:对 Text 字段打开 fielddata,支持terms aggregation
PUT /employees/_mapping
{
  "properties" : {
    "job":{
       "type":  "text",
       "fielddata": true
    }
  }
}
 
top_hits应用场景: 当获取分桶后,桶内最匹配的顶部文档列表。
"top_hits_example": {
      "terms": { "field": "category" },
      "aggs": {
        "top_products": {
          "top_hits": {  // 获取每个桶的顶部文档
            "size": 3,
            "sort": [{ "price": { "order": "desc" } }],
            "_source": { "includes": ["name", "price"] }
          }
        }
      }
    }

 

Range 聚合(数值范围)

{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          { "to": 100 },                     // 0-100
          { "from": 100, "to": 500 },        // 100-500
          { "from": 500 }                    // 500以上
        ],
        "keyed": true  // 返回对象形式而非数组
      },
      "aggs": {
        "category_stats": {
          "terms": { "field": "category.keyword" }
        }
      }
    }
  }
}

// 使用 keyed 后返回格式:
// {
//   "*-100": { ... },
//   "100-500": { ... },
//   "500-*": { ... }
// }

Date Range 聚合(日期范围)

{
  "aggs": {
    "date_ranges": {
      "date_range": {
        "field": "created_at",
        "format": "yyyy-MM-dd",
        "ranges": [
          { "to": "now-30d/d" },           // 30天前
          { "from": "now-30d/d", "to": "now" },  // 最近30天
          { "from": "now" }                // 现在开始
        ],
        "time_zone": "+08:00"  // 时区
      }
    }
  }
}

Histogram 聚合(直方图)

{
  "aggs": {
    "price_histogram": {
      "histogram": {
        "field": "price",
        "interval": 100,                  // 固定间隔
        "min_doc_count": 1,               // 最小文档数
        "extended_bounds": {              // 扩展边界
          "min": 0,
          "max": 1000
        },
        "order": { "_key": "asc" }        // 按桶的键排序
      }
    },
    
    "variable_histogram": {
      "variable_width_histogram": {       // 可变宽度直方图
        "field": "price",
        "buckets": 10                     // 目标桶数量
      }
    }
  }
}

Date Histogram 聚合(时间直方图)

{
  "aggs": {
    "sales_over_time": {
      "date_histogram": {
        "field": "created_at",
        "calendar_interval": "1M",        // 日历间隔:1天、1周、1月等
        "fixed_interval": "30d",          // 固定间隔:30天
        "format": "yyyy-MM",
        "time_zone": "+08:00",
        "min_doc_count": 0,               // 允许空桶
        "extended_bounds": {
          "min": "2023-01-01",
          "max": "2023-12-31"
        },
        "missing": "1970-01-01"           // 处理缺失值
      }
    }
  }
}

 

3、管道聚合(Pipeline Aggregations)

管道聚合是对其他聚合的结果进行再聚合。常见的管道聚合有:

  • avg_bucket:计算桶的平均值

  • sum_bucket:计算桶的总和

  • max_bucket:计算桶的最大值

  • min_bucket:计算桶的最小值

  • derivative:计算相邻桶的导数

示例:

{
  "aggs": {
    "sales_over_time": {
      "date_histogram": {
        "field": "created_at",
        "calendar_interval": "1M"
      },
      "aggs": {
        "monthly_sales": { "sum": { "field": "amount" } },
        
        //  最大值桶
        "max_month": {
          "max_bucket": {
            "buckets_path": "monthly_sales"
          }
        },
        
        // 平均桶
        "avg_monthly_sales": {
          "avg_bucket": {
            "buckets_path": "monthly_sales"
          }
        },
        // 桶排序
        "sales_bucket_sort": {
          "bucket_sort": {
            "sort": [
              { "monthly_sales": { "order": "desc" } }
            ],
            "from": 0,          // 跳过前N个桶
            "size": 10          // 返回桶数量
          }
        }
      }
    }
  }
}

 

 

 

posted @ 2026-01-07 15:03  邓维-java  阅读(0)  评论(0)    收藏  举报