如何获取文档集中所有非空字段的名称?
获取文档集中所有非空字段名称的方法
需求背景
给定示例文档:
{ "a1":"v1", "a2":null, "f1":"v3", "f2":"", "f3":"v3" }
需要提取所有非空(值不为null且不为空字符串)的字段名称,预期结果:a1,f1,f3
现有方案的问题
- 手动为每个字段编写
exists过滤聚合:能得到单个字段的非空计数,但字段数量多时操作繁琐,扩展性差。 - 使用通配符
*的exists聚合:只能返回总非空字段的文档数,无法按字段名称拆分结果。
可行解决方案:脚本聚合遍历字段
通过Painless脚本遍历每个文档的字段,筛选出非空字段后,对字段名进行聚合去重,直接得到目标列表。
完整DSL查询示例
{ "size": 0, // 不需要返回原始文档,只取聚合结果 "aggs": { "non_empty_fields": { "terms": { "script": { "source": """ def validFields = []; // 遍历当前文档的所有字段 for (def entry : params._source.entrySet()) { def val = entry.getValue(); // 过滤掉null和空字符串的字段 if (val != null && val != "") { validFields.add(entry.getKey()); } } return validFields; """, "lang": "painless" }, "size": 1000 // 根据实际字段总数调整,避免结果截断 } } } }
结果解析
执行后会返回类似如下结构的聚合结果,直接提取buckets中的key值即可得到非空字段列表:
{ "aggregations": { "non_empty_fields": { "buckets": [ {"key": "a1", "doc_count": 1}, {"key": "f1", "doc_count": 1}, {"key": "f3", "doc_count": 1} ] } } }
注意事项
- 若文档包含嵌套字段,需要修改脚本逻辑,通过递归遍历嵌套结构中的字段。
- 当文档量极大时,脚本遍历会有一定性能开销,建议先通过过滤条件缩小查询范围。
- 调整
size参数值,确保能覆盖所有非空字段,避免结果被截断。
内容的提问来源于stack exchange,提问作者beatrice
相关产品推荐
相关产品推荐

