如何统计Elasticsearch中字段含重复值的文档数量?
在Elasticsearch中统计含重复值字段的文档数量
要统计索引中searchProperties.duplicated-attr字段存在重复值(如test test)的文档数量,可以通过Painless脚本查询实现,以下是具体方案:
核心思路
利用Painless脚本解析字段的完整字符串值(通过keyword子字段避免分词干扰),将值按空格拆分后去重,比较原拆分数组长度与去重后的集合大小——若两者不等,说明字段值包含重复元素。
统计文档数量(Count API)
直接调用_count API获取符合条件的文档总数:
GET /你的索引名称/_count { "query": { "bool": { "filter": { "script": { "script": { "source": "def value = doc['searchProperties.duplicated-attr.keyword'].value; if (value == null) return false; def cleaned = value.trim().replaceAll('\\\\s+', ' '); if (cleaned.isEmpty()) return false; def parts = cleaned.split(' '); def uniqueParts = new HashSet(parts); return parts.length != uniqueParts.size();", "lang": "painless" } } } } } }
查看具体文档(Search API)
如果需要查看符合条件的文档内容,使用_search API,可指定返回字段以优化性能:
GET /你的索引名称/_search { "query": { "bool": { "filter": { "script": { "script": { "source": "def value = doc['searchProperties.duplicated-attr.keyword'].value; if (value == null) return false; def cleaned = value.trim().replaceAll('\\\\s+', ' '); if (cleaned.isEmpty()) return false; def parts = cleaned.split(' '); def uniqueParts = new HashSet(parts); return parts.length != uniqueParts.size();", "lang": "painless" } } } } }, "_source": ["searchProperties.duplicated-attr"] // 仅返回目标字段 }
关键说明
- 使用keyword子字段:由于
duplicated-attr的text类型会被分词,必须通过.keyword子字段获取完整原始字符串,否则无法准确判断重复值。 - 处理特殊情况:脚本中已处理
null值、空字符串、多空格场景,避免查询报错或误判。 - 性能提示:脚本查询需实时计算,适用于中小规模索引;若索引数据量极大,建议在文档写入时提前标记是否存在重复值(如新增
has-duplicated-value布尔字段),后续直接通过普通查询统计,提升性能。
内容的提问来源于stack exchange,提问作者Sam J Sem
相关产品推荐
相关产品推荐

