MongoDB聚合:不使用unwind统计含指定name值的文档数量
MongoDB聚合统计:不使用unwind统计包含指定name的文档数量
解决方案
通过MongoDB的数组聚合操作实现,全程不对原始parameter数组使用unwind,具体聚合管道如下:
db.collection.aggregate([ // 提取每个文档中parameter数组的唯一name值(同一文档内重复name仅算一次) { $project: { uniqueNames: { $setUnion: ["$parameter.name"] } } }, // 收集所有文档的唯一name集合到一个数组 { $group: { _id: null, allNameGroups: { $push: "$uniqueNames" } } }, // 累计每个name出现的文档数,并转换为期望格式 { $project: { result: { $map: { input: { $objectToArray: { $reduce: { input: "$allNameGroups", initialValue: {}, in: { $mergeObjects: [ "$$value", { $arrayToObject: { $map: { input: "$$this", as: "name", in: { k: "$$name", v: { $add: [{ $ifNull: ["$$value.$$name", 0] }, 1] } } } } } ] } } } }, as: "item", in: { _id: { $concat: ["$$item.k", " contain records"] }, count: "$$item.v" } } }, _id: 0 } }, // 展开结果数组为独立文档(此unwind仅处理最终结果数组,未操作原始数据) { $unwind: "$result" }, { $replaceRoot: { newRoot: "$result" } } ])
执行结果
[ { "_id": "name1 contain records", "count": 2 }, { "_id": "name2 contain records", "count": 1 }, { "_id": "name3 contain records", "count": 1 } ]
关键操作说明
$setUnion: ["$parameter.name"]:自动对当前文档的parameter.name数组去重,得到该文档包含的唯一name集合$reduce遍历所有文档的name集合,通过$mergeObjects和$arrayToObject累计每个name的出现文档数:每遇到一个包含该name的文档,计数加1$objectToArray将计数对象转为键值对数组,再用$map转换为需求指定的输出格式- 最后两步的
$unwind和$replaceRoot仅用于将嵌套结果数组展开为顶层文档,未对原始的parameter数组执行unwind,符合要求
内容的提问来源于stack exchange,提问作者sajeeth
相关产品推荐
相关产品推荐

