适用版本: 7.3-7.7
1. 错误异常的基本描述 #
Aggregation [name] cannot support regular expression style include/exclude settings as they can only be applied to string fields 是 Elasticsearch 在执行聚合(Aggregation)阶段抛出的异常。该错误明确指出:正则表达式形式的 include / exclude 筛选条件只能应用于字符串类型的字段,当前聚合所引用的字段不满足此条件。
常见现象 #
- 搜索请求返回 HTTP
400 Bad Request,响应体中包含search_phase_execution_exception或aggregation_execution_exception。 - Kibana 可视化面板加载失败,Dev Tools 中执行对应查询立即报错。
- 应用日志中出现
AggregationExecutionException堆栈,伴随illegal_argument_exception信息。 - 仅影响使用了正则
include/exclude的聚合请求,普通搜索和未使用该特性的聚合请求正常。
典型报错与异常栈 #
{
"error": {
"root_cause": [
{
"type": "aggregation_execution_exception",
"reason": "Aggregation [my_agg] cannot support regular expression style include/exclude settings as they can only be applied to string fields. Use an array of values for include/exclude clauses"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"failed_shards": 1,
"caused_by": {
"type": "aggregation_execution_exception",
"reason": "Aggregation [my_agg] cannot support regular expression style include/exclude settings as they can only be applied to string fields. Use an array of values for include/exclude clauses"
}
},
"status": 400
}
对应 Java 异常栈:
org.elasticsearch.search.aggregations.AggregationExecutionException: Aggregation [my_agg] cannot support regular expression style include/exclude settings as they can only be applied to string fields. Use an array of values for include/exclude clauses
at org.elasticsearch.search.aggregations.bucket.terms.GlobalOrdinalsStringTermsAggregator.build(GlobalOrdinalsStringTermsAggregator.java:...)
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory.create(TermsAggregatorFactory.java:...)
2. 为什么会发生这个错误 #
该异常的根本原因是:对不支持正则表达式筛选的字段类型使用了正则形式的 include / exclude。
Elasticsearch 的 terms 聚合支持通过 include 和 exclude 参数对桶(bucket)进行过滤,支持两种形式:
| 形式 | 示例 | 适用字段类型 |
|---|---|---|
| 正则表达式 | "include": ".*foo.*" | 仅限 keyword / text 等字符串类型字段 |
| 精确值数组 | "include": ["foo", "bar"] | 所有支持 terms 聚合的字段类型 |
当聚合字段为数值类型(long、integer、double 等)、boolean、date、ip 等非字符串类型时,使用正则表达式形式的 include/exclude 就会触发该异常。
常见触发场景 #
- 对
integer、long、double等数值字段执行terms聚合,并配置了正则形式的include/exclude。 - 聚合字段的 mapping 类型为
boolean、date、ip,却使用了".*true.*"之类的正则过滤。 - 字段原本是
keyword类型,但索引重建或 mapping 变更后变成了数值类型,导致原有查询报错。 - 使用
doc_values为false的字符串字段进行聚合(虽然这通常报其他错误,但可能叠加出现)。
3. 如何排查这个异常 #
建议按以下步骤定位问题:
3.1 确认聚合字段的 mapping 类型 #
# 查看目标索引的 mapping
GET /your_index/_mapping/field/your_field
重点关注字段的 type 值,确认是否为 keyword、text 以外的类型。
3.2 检查聚合 DSL 中的 include/exclude 写法 #
{
"aggs": {
"my_agg": {
"terms": {
"field": "status_code",
"include": ".*200.*", // ← 如果 status_code 是 long/integer 类型,这里就会报错
"size": 10
}
}
}
}
3.3 确认是否为跨索引查询导致 #
当使用通配符索引模式(如 log-*)时,不同索引的同一字段可能 mapping 不一致:
# 检查所有相关索引的 mapping
GET /log-*/_mapping/field/status_code
如果部分索引中该字段为 keyword,部分为 long,则查询在这些索引上执行时会报错。
4. 如何解决这个错误 #
方案一:将 include/exclude 改为数组形式(推荐) #
正则形式只适用于字符串字段,对于数值或日期字段,改用精确值数组:
{
"aggs": {
"status_agg": {
"terms": {
"field": "status_code",
"include": [200, 201, 204],
"size": 10
}
}
}
}
方案二:将字段改为 keyword 类型后使用正则 #
如果业务上确实需要对字段使用正则匹配,需确保字段为 keyword 类型:
# 创建新索引并指定正确 mapping
PUT /your_index_new
{
"mappings": {
"properties": {
"status_code": {
"type": "keyword"
}
}
}
}
# 使用 reindex 迁移数据
POST /_reindex
{
"source": { "index": "your_index" },
"dest": { "index": "your_index_new" }
}
之后即可使用正则形式:
{
"aggs": {
"status_agg": {
"terms": {
"field": "status_code",
"include": ".*200.*",
"size": 10
}
}
}
}
方案三:移除 include/exclude 并在应用层过滤 #
如果正则筛选逻辑不复杂,可以在聚合返回后在应用层进行过滤,避免在 Elasticsearch 侧触发异常:
{
"aggs": {
"status_agg": {
"terms": {
"field": "status_code",
"size": 100
}
}
}
}
方案四:使用 script 实现复杂过滤(性能敏感场景慎用) #
{
"aggs": {
"status_agg": {
"terms": {
"script": {
"source": "doc['status_code'].value.toString()",
"lang": "painless"
},
"include": ".*200.*",
"size": 10
}
}
}
}
5. 预防与最佳实践 #
- Mapping 设计阶段明确字段用途:如果计划对某个字段做正则过滤的聚合,务必将其设置为
keyword类型,避免使用数值类型存储枚举值。 - 跨索引查询前统一 mapping:使用 Index Template 或 Component Template 确保所有相关索引的字段类型一致,避免
log-2023-01和log-2023-02中同一字段类型不同。 - 避免在数值字段上使用正则 include/exclude:数值字段的
terms聚合应使用精确值数组形式的include/exclude,或完全省略该参数。 - 在 Kibana 可视化中注意字段类型:Kibana 的字段选择下拉框不会区分字段类型是否支持正则,使用正则过滤前需确认字段类型。
- 使用运行时字段(Runtime Field)作为过渡方案:如果无法修改原始 mapping,可以通过运行时字段将数值字段转换为字符串类型后再聚合:
{
"runtime": {
"status_code_str": {
"type": "keyword",
"script": {
"source": "emit(doc['status_code'].value.toString())"
}
}
},
"aggs": {
"status_agg": {
"terms": {
"field": "status_code_str",
"include": ".*200.*",
"size": 10
}
}
}
}
借助 INFINI 产品提升排障效率 #
- INFINI Console 可查看集群各索引的 mapping 差异、聚合请求失败趋势,快速定位跨索引 mapping 不一致问题。
- INFINI Gateway 可部署在 Elasticsearch 前端,对包含非法正则
include/exclude的请求进行拦截和改写,避免异常请求到达集群。
6. 小结 #
Aggregation cannot support regular expression style include/exclude 异常的核心原因是字段类型与 include/exclude 的形式不匹配。修复的关键是根据字段类型选择正确的过滤形式:字符串字段用正则,数值字段用精确值数组。在设计 mapping 时提前规划字段用途,是避免此类问题的最有效手段。
相关错误 #
- unregistered-aggregation-aggregationname:未注册的聚合
- unsupported-aggregation-type:不支持的聚合类型
- valuessource-type-valuessource-tostring-is-not-supported-for-aggregation:ValueSource类型不支持聚合
- unsupported-operation-parsed-aggregations-are-null:聚合解析为空
- aggregation-execution-exception:聚合执行异常
附:源码上下文 #
以下为触发该异常的 Elasticsearch 源码片段,便于深入理解其触发条件:
if (valuesSource instanceof ValuesSource.Bytes) {
ExecutionMode execution = ExecutionMode.MAP;
DocValueFormat format = config.format();
if ((includeExclude != null) && (includeExclude.isRegexBased()) && format != DocValueFormat.RAW) {
throw new AggregationExecutionException("Aggregation [" + name + "] cannot support " +
"regular expression style include/exclude settings as they can only be applied to string fields. " +
"Use an array of values for include/exclude clauses");
}
return execution.create(name, factories, valuesSource, format,
...
}





