如何用MongoDB聚合查询将N个文档的数组转为单个文档
用MongoDB聚合将数组文档合并为单个文档
嘿,这个需求其实用MongoDB聚合里的$reduce搭配$mergeObjects就能完美解决,我来给你详细说下实现方式:
核心思路
我们需要遍历loop数组中的每一个子文档,把它们的键值对逐一合并成一个单独的文档。$mergeObjects专门用来合并多个文档的键值对,而$reduce可以帮我们迭代整个数组,完成累积合并的操作。
具体聚合管道代码
db.yourCollectionName.aggregate([ { $addFields: { loop: { $reduce: { input: "$loop", initialValue: {}, in: { $mergeObjects: ["$$value", "$$this"] } } } } } ])
代码拆解
$addFields:这个阶段会替换掉原文档中的loop字段(如果原字段存在),把合并后的单个文档赋值给它。$reduce:input:指定要处理的目标数组,也就是我们的$loop数组。initialValue:设置合并的初始值为一个空对象{},作为合并的起点。in:这里是每一次迭代的逻辑,用$mergeObjects把当前累积的对象($$value,也就是上一步合并后的结果)和数组里的当前子文档($$this)合并到一起。
效果验证
针对你给出的输入:
"loop": [ { "field1": "1" }, { "field2": "2", "field3": "3" }, { "field4": "4" }, { "field5": "5", "field6": "6" } ]
经过上面的聚合处理后,输出正好是你想要的:
"loop": { "field1": "1", "field2": "2", "field3": "3", "field4": "4", "field5": "5", "field6": "6" }
额外说明
如果数组中的子文档存在重复字段名,比如两个子文档都有field1,那么后面的子文档中的字段值会覆盖前面的,这是$mergeObjects的默认特性,使用时需要注意这一点哦。
内容的提问来源于stack exchange,提问作者Matthew
相关产品推荐
相关产品推荐

