如何统计索引中Views.Washington数组内的唯一对象数量
统计Elasticsearch数组中唯一键对象的数量
嘿,要统计Views.Washington数组里键名唯一的对象数量(就像你案例里结果为2,因为第一个和第三个对象的键重复了),可以利用Elasticsearch的脚本能力结合聚合来实现,下面给你两种实用的方案:
方案一:直接使用脚本聚合
这种方式不需要提前定义字段,直接在聚合里编写Painless脚本来提取键名并统计唯一值:
{ "size": 0, // 不需要返回具体文档,只看聚合结果 "aggs": { "unique_washington_views": { "cardinality": { "script": { "source": """ def uniqueKeys = new HashSet(); // 遍历Washington下的所有对象 for (item in params._source.Views.Washington) { // 提取每个对象的键名并加入集合(自动去重) for (key in item.keySet()) { uniqueKeys.add(key); } } // 返回集合的大小,也就是唯一键的数量 return uniqueKeys.size(); """, "lang": "painless" } } } } }
说明:
- 脚本里用
HashSet自动帮我们去重,最后返回集合的大小就是你要的唯一对象数量。 params._source直接访问文档的原始数据,确保能正确遍历数组里的每个对象。
方案二:用运行时字段+聚合(更清晰易维护)
如果你需要多次做这类统计,可以先定义一个运行时字段提取所有键名,再基于这个字段做聚合:
{ "size": 0, "runtime_mappings": { // 定义一个运行时字段,提取Washington下的所有键名 "washington_viewer_keys": { "type": "keyword", "script": """ def keys = []; for (item in params._source.Views.Washington) { for (key in item.keySet()) { keys.add(key); } } emit(keys); // 把所有键名作为多值字段输出 """ } }, "aggs": { "unique_view_count": { // 统计多值字段的唯一值数量 "cardinality": { "field": "washington_viewer_keys" } } } }
注意事项:
- 如果你的数据量极大,
cardinality聚合是近似统计(误差可控);如果需要100%精确值,可以改用terms聚合(设置足够大的size),然后统计返回的bucket数量,但这种方式性能消耗更高,适合小数据量场景。 - 确保你的Elasticsearch版本支持Painless脚本(Elasticsearch 5.0+都默认支持)。
内容的提问来源于stack exchange,提问作者Grim Reaper
相关产品推荐
相关产品推荐

