Elasticsearch如何实现不区分大小写的字段值去重查询
Elasticsearch 不区分大小写去重实现方案
完全可以通过查询语句实现该需求,根据是否可修改索引配置,有两种可行方案:
方案1:无需调整Mapping,临时查询使用脚本聚合
如果不能修改现有索引配置,可以直接在terms聚合中通过Painless脚本将字段值统一转为小写后再分组,示例语句如下:
GET /你的索引名/_search { "size": 0, "aggs": { "case_insensitive_unique": { "terms": { "script": { "source": "doc['你的字段名.keyword'].value.toLowerCase()", "lang": "painless" }, "size": 1000 } } } }
- 注意事项:
- 替换语句中的
你的索引名、你的字段名为实际业务的索引和字段名称,确保目标字段有keyword类型的子字段 - 如果字段可能存在空值,可以在脚本中增加空值判断避免报错,脚本示例:
"source": "if(doc['你的字段名.keyword'].size() == 0) {return '';} else {return doc['你的字段名.keyword'].value.toLowerCase();}" - 该方案不需要调整索引配置,但聚合时需要对所有匹配文档做脚本计算,数据量较大时性能偏低,适合临时查询场景
- 替换语句中的
方案2:调整Mapping添加normalizer,长期使用性能更优
如果该去重需求是长期业务需求,建议提前在字段Mapping中配置小写normalizer,写入数据时就完成归一化处理,后续查询性能更高。
步骤1:配置索引normalizer(已有索引需先关闭索引再修改settings,修改完成后重新打开)
PUT /你的索引名 { "settings": { "analysis": { "normalizer": { "lowercase_normalizer": { "type": "custom", "filter": ["lowercase"] } } } }, "mappings": { "properties": { "你的字段名": { "type": "text", "fields": { "keyword": { "type": "keyword", "normalizer": "lowercase_normalizer" } } } } } }
步骤2:直接用原生terms聚合实现不区分大小写去重
GET /你的索引名/_search { "size": 0, "aggs": { "case_insensitive_unique": { "terms": { "field": "你的字段名.keyword", "size": 1000 } } } }
该方案所有归一化逻辑在数据写入时完成,查询时无额外计算开销,性能远高于脚本方案,适合高频使用的业务场景。
内容的提问来源于stack exchange,提问作者s.h.moghaddasi
相关产品推荐
相关产品推荐

