如何在MongoDB聚合中统计嵌套数组对象内的URL值
MongoDB多层嵌套数组统计方案
先给个典型的文档示例(方便对应步骤理解):
{ "_id": ObjectId("60d21b4667d0d8992e610c85"), "iocs": [ { "type": "malware", "urls": ["http://example.com/mal1", "http://example.com/common"] }, { "type": "phishing", "urls": ["http://example.com/phish1", "http://example.com/common"] } ] }
直接上完整的聚合查询,再逐个阶段拆解:
db.collection.aggregate([ // 第一步:展开iocs数组,每个iocs元素成为独立文档 { $unwind: "$iocs" }, // 第二步:展开每个iocs下的urls数组,每个url成为独立文档,同时保留对应的type { $unwind: "$iocs.urls" }, // 第三步:按url分组,统计出现次数,收集并去重type { $group: { _id: "$iocs.urls", count: { $sum: 1 }, types: { $addToSet: "$iocs.type" } // $addToSet自动去重重复的type } }, // 可选:重命名字段让输出更直观 { $project: { _id: 0, url: "$_id", count: 1, types: 1 } } ])
各阶段作用说明
- $unwind: "$iocs":把外层的iocs数组拆成单个文档,每个文档包含原文档的其他字段 + 一个iocs对象(包含type和对应的urls数组)。
- $unwind: "$iocs.urls":把每个iocs对象里的urls数组再拆成单个文档,此时每个文档对应一个url + 对应的type,这是后续分组统计的基础。
- $group:
_id: "$iocs.urls":指定按url值分组,相同url会被归为一组。count: { $sum: 1 }:每出现一次该url,计数加1。types: { $addToSet: "$iocs.type" }:用$addToSet收集该url关联的所有type,自动过滤重复值,最终得到唯一的type集合。
- $project:可选步骤,把默认的
_id字段替换为更易懂的url字段,调整输出格式。
输出结果示例
[ { "url": "http://example.com/mal1", "count": 1, "types": ["malware"] }, { "url": "http://example.com/common", "count": 2, "types": ["malware", "phishing"] }, { "url": "http://example.com/phish1", "count": 1, "types": ["phishing"] } ]
内容的提问来源于stack exchange,提问作者Mbay
相关产品推荐
相关产品推荐

