查询Elasticsearch 5.4中存储空对象值的文档数量
解决Elasticsearch 5.4中空对象文档的统计问题
要精准统计存储空对象(即"somefield": {})的文档数量,同时排除无该字段、字段未定义或包含子属性的对象,你需要组合exists查询和脚本判断来实现。下面是具体的解决方案:
核心思路
你的需求的关键点在于区分三种情况:
- 要匹配:字段存在且是没有任何子属性的空对象
- 要排除:字段不存在 / 字段值未定义 / 字段是带有子属性的对象(如
"somefield": {"field1": "value1"})
之前的查询错误返回带属性的对象,大概率是因为只检查了字段存在,没有判断对象是否真正为空。在Elasticsearch中,空对象的特征是其内部没有任何子字段,我们可以通过脚本查询来验证这一点。
正确的查询示例
使用_count API统计符合条件的文档数量,查询语句如下:
GET /你的索引名称/_count { "query": { "bool": { "filter": [ // 确保字段存在,排除无该字段或未定义的情况 { "exists": { "field": "somefield" } }, // 脚本判断对象是否为空(子字段数量为0) { "script": { "script": { "source": "doc['somefield'].size() == 0", "lang": "painless" } } } ] } } }
各部分说明
exists查询:确保文档确实包含somefield字段,直接排除没有该字段或字段未定义的文档。- Painless脚本查询:
doc['somefield'].size()会返回该对象包含的子字段数量,空对象的子字段数量为0,带有属性的对象则大于0,通过这个判断精准筛选出空对象。
优化说明
使用filter而非must是因为统计计数不需要计算文档评分,filter会缓存结果,查询效率更高。如果你的场景需要参与评分(比如在搜索结果中筛选),把filter换成must即可。
注意事项
如果运行脚本时遇到权限错误,需要检查Elasticsearch配置文件elasticsearch.yml,确保开启了inline脚本支持(仅建议在开发环境使用):
script.inline: true script.stored: true
内容的提问来源于stack exchange,提问作者AJP
相关产品推荐
相关产品推荐

