Skip to content

聚合分析

聚合类型总览

┌─────────────────────────────────────────┐
│              Aggregations               │
├─────────────────────────────────────────┤
│                                          │
│  1. Metric(度量聚合)                    │
│     - avg / sum / min / max             │
│     - cardinality / percentiles       │
│                                          │
│  2. Bucket(桶聚合)                     │
│     - terms / range / date_histogram   │
│     - filter / significant_terms      │
│                                          │
│  3. Pipeline(管道聚合)                 │
│     - cumulative_sum / moving_avg      │
│     - derivative / percentiles_bucket │
└─────────────────────────────────────────┘

1. Metric聚合

基本统计

json
POST /products/_search
{
  "size": 0,
  "aggs": {
    "avg_price": {"avg": {"field": "price"}},
    "max_price": {"max": {"field": "price"}},
    "min_price": {"min": {"field": "price"}},
    "sum_price": {"sum": {"field": "price"}},
    "stats_price": {"stats": {"field": "price"}}
  }
}

计数相关

json
// 值计数(有值的文档数)
{
  "aggs": {
    "count": {"value_count": {"field": "price"}}
  }
}

// 唯一值数量(近似)
{
  "aggs": {
    "unique_brands": {"cardinality": {"field": "brand"}}
  }
}

// 百分位(近似)
{
  "aggs": {
    "price_percentiles": {
      "percentiles": {
        "field": "price",
        "percents": [25, 50, 75, 95]
      }
    }
  }
}

// 百分位排名
{
  "aggs": {
    "price_percentile_ranks": {
      "percentile_ranks": {
        "field": "price",
        "values": [100, 500, 1000]
      }
    }
  }
}

stats

json
{
  "aggs": {
    "price_stats": {"stats": {"field": "price"}}
  }
}

// 结果
{
  "price_stats": {
    "count": 100,
    "min": 100,
    "max": 9999,
    "avg": 2500.5,
    "sum": 250050
  }
}

2. Bucket聚合

terms聚合

json
// 按品牌分组
POST /products/_search
{
  "size": 0,
  "aggs": {
    "by_brand": {
      "terms": {
        "field": "brand.keyword",
        "size": 10,
        "order": {"_count": "desc"}
      }
    }
  }
}

range聚合

json
// 价格区间
{
  "aggs": {
    "price_ranges": {
      "range": {
        "field": "price",
        "ranges": [
          {"to": 500},
          {"from": 500, "to": 1000},
          {"from": 1000, "to": 2000},
          {"from": 2000}
        ]
      }
    }
  }
}

date_histogram

json
// 按月统计
{
  "aggs": {
    "sales_by_month": {
      "date_histogram": {
        "field": "create_date",
        "calendar_interval": "month"
      }
    }
  }
}

// 按天,偏移8小时
{
  "aggs": {
    "sales_by_day": {
      "date_histogram": {
        "field": "create_date",
        "calendar_interval": "day",
        "offset": "+8h"
      }
    }
  }
}

filter聚合

json
// 分类聚合后再聚合
{
  "aggs": {
    "active_products": {
      "filter": {"term": {"status": "active"}},
      "aggs": {
        "avg_price": {"avg": {"field": "price"}}
      }
    }
  }
}

significant_terms

json
// 发现异常项(与背景对比)
{
  "aggs": {
    "significant_brands": {
      "significant_terms": {
        "field": "brand.keyword",
        "size": 5
      }
    }
  }
}

3. Pipeline聚合

cumulative_sum

json
// 累计求和
POST /sales/_search
{
  "size": 0,
  "aggs": {
    "sales_by_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales_sum": {"sum": {"field": "amount"}},
        "cumulative_sales": {
          "cumulative_sum": {
            "buckets_path": "sales_sum"
          }
        }
      }
    }
  }
}

moving_avg

json
// 移动平均
{
  "aggs": {
    "sales_by_month": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "month"
      },
      "aggs": {
        "sales_sum": {"sum": {"field": "amount"}},
        "moving_avg_sales": {
          "moving_avg": {
            "buckets_path": "sales_sum",
            "window": 3,
            "model": "simple"
          }
        }
      }
    }
  }
}

子聚合与多级聚合

多级聚合

json
POST /products/_search
{
  "size": 0,
  "aggs": {
    "by_category": {
      "terms": {"field": "category.keyword"},
      "aggs": {
        "by_brand": {
          "terms": {"field": "brand.keyword", "size": 5},
          "aggs": {
            "avg_price": {"avg": {"field": "price"}}
          }
        }
      }
    }
  }
}

嵌套聚合

json
// 嵌套类型聚合
{
  "aggs": {
    "comments": {
      "nested": {"path": "comments"},
      "aggs": {
        "avg_rating": {"avg": {"field": "comments.rating"}}
      }
    }
  }
}

面试考点

Q: terms聚合分片问题?

  • 每个分片返回top N,合并后可能不准确
  • 设置shard_size参数优化

Q: 聚合慢怎么优化?

  • filter替代bool must
  • 减少数据量(加过滤条件)
  • 调整精度(precision_threshold)

Q: cardinality原理?

  • HyperLogLog算法,近似值
  • 节省内存,允许误差

Q: pipeline聚合前提?

  • 需要父聚合返回多个bucket
  • 使用buckets_path引用

最后更新: