如何在MongoDB聚合中用字段值作为键统计在线机器数
问题描述
现有Nmap扫描结果的MongoDB文档结构如下:
_id: 64940937ab90b8acfa5386fb ip : "1.2.3.4" top_ports: Object --> 12.168.16.253: Object --> state: Object ----> state : "up"
需求是统计处于up状态的机器数量,已尝试执行$unwind操作:
$unwind { path: "$top_ports", }
但无法通过ip字段值作为匹配键执行$match,尝试过$set结合$objectToArray但遇到瓶颈,需要在MongoDB Compass中完成聚合,后续用于MongoDB Charts。
解决方案
因为top_ports内的键是动态IP(如12.168.16.253),无法通过固定字段名直接匹配,需先将对象转为键值对数组,再执行后续操作,完整聚合流程如下:
- 将top_ports对象转为键值数组
使用$set配合$objectToArray,把动态IP和对应状态对象转换为k(IP值)、v(状态数据)格式的数组:
{ $set: { top_ports: { $objectToArray: "$top_ports" } } }
- 展开top_ports数组
对转换后的数组执行$unwind:
{ $unwind: "$top_ports" }
- 匹配状态为up的条目
此时可通过top_ports.v.state.state匹配up状态,若需关联文档自身的ip字段,直接引用即可:
{ $match: { "top_ports.v.state.state": "up" // 如需匹配特定IP的文档,可添加:"ip": "目标IP" } }
- 统计符合条件的机器数量
最后用$group完成总数统计:
{ $group: { _id: null, up_count: { $sum: 1 } } }
完整聚合管道(可直接在MongoDB Compass中粘贴使用):
[ { $set: { top_ports: { $objectToArray: "$top_ports" } } }, { $unwind: "$top_ports" }, { $match: { "top_ports.v.state.state": "up" } }, { $group: { _id: null, up_count: { $sum: 1 } } } ]
说明:转换后的top_ports.k对应动态IP值,top_ports.v对应该IP的状态对象,以此实现精准匹配与统计。
内容的提问来源于stack exchange,提问作者yary
相关产品推荐
相关产品推荐

