适用版本: 6.8-7.7
1. 错误异常的基本描述 #
Aggregation [name] cannot support regular expression style include/exclude settings as they can only be applied to string fields 是 Elasticsearch 在执行聚合查询时抛出的异常。该错误的核心含义是:当前聚合类型为数值类型字段(numeric field)使用了正则表达式风格的 include / exclude 过滤,而正则表达式过滤仅支持 keyword 字符串类型的字段。
常见现象 #
- 搜索接口返回 HTTP
400 Bad Request,响应体中包含illegal_argument_exception或aggregation_execution_exception。 - Kibana 或其他可视化工具中配置的聚合图表无法正常渲染,控制台显示报错信息。
- 应用日志中出现类似
AggregationExecutionException: Aggregation [xxx] cannot support regular expression style 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 numeric values for include/exclude clauses used to filter numeric fields"
}
],
"type": "search_phase_execution_exception",
"reason": "all shards failed",
"failed_shards": [
{
"reason": {
"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 numeric values for include/exclude clauses used to filter numeric fields"
}
}
]
},
"status": 400
}
服务端日志中的异常栈通常类似:
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.
at org.elasticsearch.search.aggregations.bucket.terms.TermsAggregatorFactory.buildAggregator(TermsAggregatorFactory.java:...)
at org.elasticsearch.search.aggregations.AggregatorFactories.execute(AggregatorFactories.java:...)
2. 为什么会发生这个错误 #
该错误的根本原因是:Elasticsearch 的 include / exclude 参数在 terms 聚合中对字符串字段和数值字段提供了两种不同的过滤机制:
| 字段类型 | 支持的 include/exclude 形式 | 说明 |
|---|---|---|
keyword / 字符串字段 | 正则表达式(regex)或精确值数组 | 正则表达式通过 Java 内置正则引擎匹配字符串 |
数值字段(long、integer、double 等) | 仅支持精确值数组 | 数值无法进行正则匹配,只能按值过滤 |
当聚合配置同时满足了以下两个条件时,就会触发此异常:
- 聚合目标是 数值类型字段(
long、integer、short、byte、double、float等); include或exclude的值被识别为 正则表达式形式(而非数值数组)。
常见触发场景 #
- 对数值字段使用字符串形式的正则表达式进行过滤,例如
"include": "^[0-9]+$",ES 无法对数值做正则匹配。 - 从旧版配置或脚本中复制了针对
keyword字段的聚合 DSL,但字段类型已变更为数值类型,未同步调整include/exclude的写法。 - 在
rare_terms聚合中使用正则形式的include/exclude,而该聚合在部分版本中对数值字段有相同限制。 - 动态脚本或应用代码中拼装 DSL 时,未根据字段类型区分
include/exclude的格式。
3. 如何排查这个异常 #
第一步:确认报错聚合的完整 DSL #
从应用日志、Kibana 开发者工具或网关访问日志中获取触发异常的完整查询 DSL,重点检查:
- 聚合中
terms(或rare_terms)的field值指向哪个字段; - 该字段的
include/exclude配置的具体内容; - 确认
include/exclude是字符串(正则)还是数组(精确值)。
第二步:检查目标字段的 mapping #
使用以下 API 查看索引中该字段的类型:
GET /your_index/_mapping/field/your_field
返回示例:
{
"your_index": {
"mappings": {
"your_field": {
"full_name": "your_field",
"mapping": {
"your_field": {
"type": "long"
}
}
}
}
}
}
如果 type 为数值类型(long、integer、double 等),则确认是本文描述的错误场景。
第三步:判断 include/exclude 的使用方式 #
检查 DSL 中 include / exclude 的写法:
// ❌ 错误写法:对数值字段使用正则表达式字符串
{
"aggs": {
"my_agg": {
"terms": {
"field": "price",
"include": "[0-9]+"
}
}
}
}
// ✅ 正确写法(数值字段):使用数值数组
{
"aggs": {
"my_agg": {
"terms": {
"field": "price",
"include": [100, 200, 300]
}
}
}
}
4. 如何解决这个错误 #
方案一:将 include/exclude 改为数值数组(推荐) #
如果聚合目标是数值字段,将 include / exclude 从正则表达式改为精确数值数组:
{
"size": 0,
"aggs": {
"filter_by_numeric_range": {
"terms": {
"field": "status_code",
"include": [200, 201, 204],
"size": 10
}
}
}
}
如果需要"范围式"过滤,可以先在 query 层用 range 或 bool 过滤,再对结果做聚合:
{
"size": 0,
"query": {
"range": {
"price": {
"gte": 100,
"lte": 500
}
}
},
"aggs": {
"price_terms": {
"terms": {
"field": "price",
"size": 20
}
}
}
}
方案二:将字段改为 keyword 类型(如需正则匹配) #
如果业务上确实需要对数值做正则风格的分组(例如按数字前缀分组),可在 mapping 中增加一个 keyword 类型的多字段(multi-field):
PUT /your_index/_mapping
{
"properties": {
"status_code": {
"type": "integer",
"fields": {
"as_keyword": {
"type": "keyword"
}
}
}
}
}
然后对新字段使用正则 include:
{
"aggs": {
"status_groups": {
"terms": {
"field": "status_code.as_keyword",
"include": "2.*",
"size": 10
}
}
}
}
方案三:使用 script 聚合实现自定义过滤 #
如果需要更复杂的数值过滤逻辑,可以用 script 在聚合阶段实现:
{
"aggs": {
"custom_numeric_filter": {
"terms": {
"script": {
"source": "doc['price'].value >= 100 && doc['price'].value <= 500 ? 'in_range' : 'out_of_range'"
}
}
}
}
}
注意:
script聚合会带来性能开销,不建议在高并发或大数据集场景下使用。
5. 如何预防此类问题 #
编码规范建议 #
- 在应用代码中根据字段类型动态决定
include/exclude的格式:字符串字段用正则,数值字段用数组。 - 为聚合 DSL 的构建增加单元测试,覆盖不同类型字段的聚合场景,防止字段类型变更后 DSL 不同步。
- 避免直接复制针对
keyword字段的聚合配置到数值字段,两者的include/exclude语义不同。
Mapping 设计建议 #
- 对既需要数值运算又需要字符串匹配过滤的字段,使用
multi-field 同时配置数值主类型和
keyword子类型。 - 在索引模板(Index Template)中明确字段类型,避免因动态 mapping 产生不符合预期的字段类型。
监控与告警 #
- 通过
INFINI Gateway 对返回
400的查询请求进行记录和采样,及时发现类似 DSL 错误。 - 在 INFINI Console 中查看集群的慢查询和错误请求趋势,定位频繁失败的聚合查询。
6. 小结 #
Aggregation cannot support regular expression style include/exclude 是一个典型的字段类型与 DSL 写法不匹配的问题。核心要点是:正则表达式形式的 include / exclude 仅适用于字符串(keyword)字段,数值字段必须使用精确值数组。
排查时先确认字段类型,再检查 include / exclude 的格式;修复时优先采用数值数组或 range 查询前置过滤;长期来看,合理的 mapping 设计和 DSL 构建规范是避免此类问题的最佳保障。
相关错误 #
- unregistered-aggregation-aggregationname:未注册的聚合
- unsupported-aggregation-type:不支持的聚合类型
- aggregation-execution-exception:聚合执行异常
- values-source-type-not-supported-for-aggregation:ValueSource类型不支持聚合
- illegal-argument-exception-in-terms-aggregation:terms聚合中的非法参数异常
附:源码上下文 #
以下为触发该异常的 Elasticsearch 源码片段,帮助理解异常抛出的条件:
if ((includeExclude != null) && (includeExclude.isRegexBased())) {
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 numeric values for include/exclude clauses "
+ "used to filter numeric fields");
}
if (valuesSource instanceof ValuesSource.Numeric) {
// 数值类型的 ValuesSource,不支持正则过滤
}





