Elasticsearch 7.17.7大小写不敏感聚合失效及原始值返回问题
解决Elasticsearch大小写不敏感聚合并返回原始值的问题
方案一:调整字段映射,分离匹配与原始值存储
当前你的name.raw字段因使用lowercase_normalizer,存储的全是小写值,导致正则匹配和原始值返回无法同时满足。需要新增一个不做归一化处理的keyword子字段,专门保留原始大小写的字段值,同时用原小写归一化字段做匹配。
- 更新索引映射:
PUT blah/_mapping { "properties": { "name": { "type": "text", "fields": { "raw": { "type": "keyword", "normalizer": "lowercase_normalizer" }, "raw_original": { "type": "keyword" // 保留原始字段的大小写格式 } } } } }
- 重新索引现有文档(旧文档不会自动填充新字段):
POST _reindex { "source": { "index": "blah" }, "dest": { "index": "blah" } }
- 执行聚合查询:通过脚本用小写归一化字段做匹配,同时返回原始值
GET blah/_search { "size": 0, "aggs": { "filtered_names": { "terms": { "field": "name.raw_original", "script": { "source": "doc['name.raw'].value =~ /new.*/" } } } } }
这样聚合结果会返回NEW YORK、New Orleans、New Hampshire等原始格式的值,同时实现大小写不敏感的正则匹配。
方案二:用Composite聚合直接读取原始值(无需修改映射)
如果不想调整现有映射,可以借助composite聚合直接读取文档原始字段值,结合脚本过滤:
GET blah/_search { "size": 0, "aggs": { "filtered_names": { "composite": { "sources": [ { "original_name": { "terms": { "field": "_source.name" } } } ], "script": { "source": "doc['name.raw'].value =~ /new.*/" } } } } }
注意:直接读取_source的性能略低于使用keyword字段,数据量较大时优先选择方案一。
关键原因说明
你的lowercase_normalizer会将所有输入值转为小写存储,所以name.raw中的值都是new york、new orleans这类格式,这就是New.*正则无法匹配的核心原因。要同时实现大小写不敏感匹配和返回原始值,必须将“用于匹配的归一化字段”和“存储原始值的字段”分开。
内容的提问来源于stack exchange,提问作者devilhector
相关产品推荐
相关产品推荐

