MongoDB中如何对比数组并统计匹配项的文档数量?
解决MongoDB统计指定数组元素对应文档数的问题
嘿,我刚好处理过类似的统计需求,给你一个能直接解决问题的MongoDB聚合方案,完全符合你的期望输出。
先看完整的聚合查询代码,你可以直接替换集合名和目标数组使用:
const targetArray = ['A', 'B', '1']; db.getCollection('mycollection').aggregate([ // 第一步:先过滤出包含目标元素的文档,减少后续处理的数据量 { $match: { locations: { $in: targetArray } } }, // 第二步:把每个文档的locations数组拆成单个元素的独立文档 { $unwind: "$locations" }, // 第三步:只保留目标数组里的元素,过滤掉无关内容 { $match: { locations: { $in: targetArray } } }, // 第四步:按元素分组,统计每个元素对应的文档总数 { $group: { _id: "$locations", count: { $sum: 1 } } }, // 最后两步:把分组结果转换成你需要的键值对格式 { $group: { _id: null, result: { $push: { k: "$_id", v: "$count" } } } }, { $replaceRoot: { newRoot: { $arrayToObject: "$result" } } } ])
每一步的作用说明:
- 第一个
$match:先筛选出locations数组包含目标数组中任意元素的文档,这样能减少后续要处理的数据量,提升查询效率。 $unwind:将每个文档的locations数组拆分成多个单元素文档,比如原文档{locations: ["A","B","C"]}会被拆成三个独立文档:{locations: "A"}、{locations: "B"}、{locations: "C"}。- 第二个
$match:过滤掉不在目标数组里的元素(比如"C"、"D"这些),确保只统计你关心的元素。 - 第一个
$group:以locations的元素为分组键,统计每个元素出现的次数——这里的次数就是包含该元素的原文档总数,因为每个原文档unwind后每个元素只对应一次。 - 最后两个阶段:把分组后的数组格式(比如
[{_id: "A", count:2}, ...])转换成你需要的键值对对象,通过$push生成键值对数组,再用$arrayToObject转换为对象,最后用$replaceRoot把这个对象作为结果返回。
执行这个查询后,你会得到完全符合预期的结果:
{ "A" : 2, "B" : 1, "1" : 1 }
扩展:如果需要保留目标数组中无匹配的元素(显示count为0)
如果你的目标数组里有元素在集合中没有匹配到任何文档,上面的查询会自动忽略它。如果需要保留这些元素并显示count: 0,可以用下面的调整版:
const targetArray = ['A', 'B', '1', 'X']; db.getCollection('mycollection').aggregate([ // 先构造包含所有目标元素的初始文档 { $documents: targetArray.map(item => ({ key: item })) }, // 左连接原集合,匹配包含当前元素的文档并统计数量 { $lookup: { from: "mycollection", let: { targetKey: "$key" }, pipeline: [ { $match: { $expr: { $in: ["$$targetKey", "$locations"] } } }, { $count: "matched" } ], as: "matches" } }, // 提取匹配数,无匹配则设为0 { $addFields: { count: { $ifNull: [{ $arrayElemAt: ["$matches.matched", 0] }, 0] } } }, // 转换为键值对对象 { $group: { _id: null, result: { $push: { k: "$key", v: "$count" } } } }, { $replaceRoot: { newRoot: { $arrayToObject: "$result" } } } ])
这个版本的结果会包含所有目标元素,比如X会显示0:
{ "A" : 2, "B" : 1, "1" : 1, "X" : 0 }
内容的提问来源于stack exchange,提问作者jones
相关产品推荐
相关产品推荐

