📣 极限科技诚招搜索运维工程师(Elasticsearch/Easysearch)- 全职/北京 👉 : 立即申请加入

为什么这个错误发生 #

aggregation_execution_exception 表示在执行聚合查询时发生错误。聚合用于对搜索结果进行统计分析,如求和、平均值、分组等。

这个错误可能由以下原因引起:

  1. 字段类型错误:聚合字段的数据类型不支持该聚合类型
  2. 字段不存在:聚合引用的字段不存在
  3. 映射冲突:字段映射与聚合操作不兼容
  4. 桶数量过多:聚合产生的桶数量超过限制
  5. 深度嵌套:聚合嵌套层级过深
  6. 脚本错误:脚本聚合中的脚本有错误
  7. 内存不足:聚合消耗过多内存触发断路器
  8. 分析器问题:基于文本字段的聚合分析器配置问题

如何修复这个错误 #

1. 检查字段映射 #

# 查看字段映射
GET /<index>/_mapping?pretty

# 确保字段类型支持聚合操作
# text 类型需要 fielddata=true 才能聚合
# keyword 类型可以直接聚合

2. 使用正确的字段类型 #

# 对文本字段使用 keyword 子字段聚合
GET /<index>/_search
{
  "aggs": {
    "group_by_field": {
      "terms": {
        "field": "field.keyword",  # 使用 .keyword
        "size": 10
      }
    }
  }
}

3. 启用 fielddata(谨慎使用) #

# 为 text 字段启用 fielddata
PUT /<index>/_mapping
{
  "properties": {
    "text_field": {
      "type": "text",
      "fielddata": true
    }
  }
}

# 注意:fielddata 会占用大量堆内存

4. 限制桶数量 #

# 使用 size 参数限制返回的桶数量
GET /<index>/_search
{
  "aggs": {
    "group_by_field": {
      "terms": {
        "field": "field.keyword",
        "size": 100  # 限制桶数量
      }
    }
  }
}

5. 使用 composite aggregation #

# 对于大量桶,使用 composite 聚合分页获取
GET /<index>/_search
{
  "aggs": {
    "my_buckets": {
      "composite": {
        "size": 1000,
        "sources": [
          { "field_name": { "terms": { "field": "field.keyword" } } }
        ]
      }
    }
  }
}

6. 修复嵌套聚合 #

# 检查聚合嵌套层级
GET /<index>/_search
{
  "aggs": {
    "level1": {
      "terms": {
        "field": "field1.keyword"
      },
      "aggs": {
        "level2": {
          "terms": {
            "field": "field2.keyword"
          }
        }
      }
    }
  }
}

7. 使用近似聚合 #

# 使用 cardinalinality 近似去重
GET /<index>/_search
{
  "aggs": {
    "unique_count": {
      "cardinality": {
        "field": "field",
        "precision_threshold": 100
      }
    }
  }
}

8. 修复脚本聚合 #

# 检查脚本语法
GET /<index>/_search
{
  "aggs": {
    "sum_field": {
      "scripted_metric": {
        "init_script": "state.count = 0",
        "map_script": "state.count += doc['field'].value",
        "combine_script": "return state.count",
        "reduce_script": "return states.sum()"
      }
    }
  }
}

9. 减少聚合范围 #

# 通过查询减少聚合的数据量
GET /<index>/_search
{
  "query": {
    "range": {
      "date": {
        "gte": "now-7d"
      }
    }
  },
  "aggs": {
    "group_by_field": {
      "terms": {
        "field": "field.keyword"
      }
    }
  }
}

10. 检查断路器状态 #

# 查看断路器状态
GET /_nodes/stats/breaker?pretty

# 如果达到限制,考虑:
# - 减少聚合复杂度
# - 增加断路器限制
# - 使用更高效的聚合类型

11. 处理 date_histogram 问题 #

# 使用正确的时间间隔
GET /<index>/_search
{
  "aggs": {
    "over_time": {
      "date_histogram": {
        "field": "date",
        "calendar_interval": "day"  # 或 "1d"
      }
    }
  }
}

12. 使用筛选后聚合 #

# 先过滤数据再聚合
GET /<index>/_search
{
  "size": 0,
  "query": {
    "bool": {
      "filter": [
        { "term": { "status": "active" } }
      ]
    }
  },
  "aggs": {
    "group_by_field": {
      "terms": {
        "field": "field.keyword"
      }
    }
  }
}

预防措施 #

  • 设计映射时考虑聚合需求
  • 使用 keyword 字段进行聚合而不是 text 字段
  • 避免在 text 字段上启用 fielddata
  • 限制聚合的桶数量和嵌套层级
  • 使用 composite aggregation 处理大量数据
  • 通过查询减少聚合的数据范围
  • 监控聚合性能和内存使用
  • 使用近似聚合提高性能