MongoDB如何统计指定IP范围的CVE字段去重元素总数及列表
解决MongoDB指定IP范围内CVE去重统计及列表获取问题
错误原因分析
你之前的聚合查询存在两个核心问题:
- 使用
$sum对字符串类型的CVE字段求和,MongoDB会将字符串解析为0,导致统计结果为0; - 按
$CVE分组的方式无法实现全局CVE去重,反而会将相同CVE数组的文档聚合在一起,不符合需求。
正确聚合实现
以下是满足需求的聚合管道,可同时完成去重CVE列表获取和数量统计:
db = db.getSiblingDB("test"); hosts = db.getCollection("test-collection"); hosts.aggregate([ // 筛选目标IP对应的文档 { $match: { "ip": { $in: ["1.2.3.4", "5.6.7.8"] } } }, // 将CVE数组拆分为单个元素文档 { $unwind: "$CVE" }, // 全局分组,收集去重后的CVE和IP列表 { $group: { _id: null, distinctCVEs: { $addToSet: "$CVE" }, targetIPs: { $addToSet: "$ip" } } }, // 格式化输出结果 { $project: { _id: 0, ip: "$targetIPs", sum_distinct_cve: { $size: "$distinctCVEs" }, CVES: "$distinctCVEs" } } ])
各阶段作用说明
$match:过滤出IP在指定范围内的文档,减少后续处理的数据量;$unwind:将每个文档的CVE数组拆分为独立文档,每个文档仅包含一个CVE元素,为全局去重做准备;$group:以_id: null进行全局分组,通过$addToSet自动去重并收集所有CVE元素和目标IP;$project:调整输出结构,用$size计算去重后CVE的总数,同时去掉冗余的_id字段,匹配预期输出格式。
运行上述查询后,将得到与你预期完全一致的结果:
{ "ip": ["1.2.3.4", "5.6.7.8"], "sum_distinct_cve": 4, "CVES": ["CVE2020-123", "CVE2022-789", "CVE2019-456", "CVE2021-469"] }
内容的提问来源于stack exchange,提问作者user19479943
相关产品推荐
相关产品推荐

