如何在MongoDB聚合中使用$map处理对象数组并提取嵌套值?
解决MongoDB动态属性展开并提取value的聚合问题
我来帮你搞定这个需求!你想要把文档里attribute_bag中的动态属性直接展开到根文档,同时提取每个属性嵌套的value值对吧?之前你的尝试思路是对的,但在变量引用上出了点小问题,我来给你修正并解释清楚。
正确的聚合管道
db.collection.aggregate([ { $replaceRoot: { newRoot: { $mergeObjects: [ "$$ROOT", { $arrayToObject: { $map: { input: { $objectToArray: "$attribute_bag" }, as: "attr", in: { k: "$$attr.k", v: "$$attr.v.value" } } } } ] } } }, { $unset: "attribute_bag" } ])
一步步解释每部分的作用
$objectToArray: "$attribute_bag":把attribute_bag这个嵌套对象转换成键值对数组。比如第一个文档会变成:[{k: "lights", v: {type: 'basic', value: '8'}}, {k: "doors", v: {type: 'basic', value: '7'}}]$map:遍历这个数组,把每个元素转换成{k: 属性名, v: 属性的value值}。这里要注意:引用$map定义的循环变量时必须用$$前缀(比如$$attr),而不是$,这是你之前写法的核心错误!$arrayToObject:把处理后的数组重新转换成对象,比如上面的例子会变成{lights: '8', doors: '7'}$mergeObjects:把原文档($$ROOT包含_id、name和attribute_bag)和新生成的属性对象合并,这样既保留了原有字段,又添加了动态展开的属性$unset:最后移除不再需要的attribute_bag字段,得到你想要的最终结构
验证结果
运行这个管道后,你的输入文档会被转换成:
{ _id: 1, name: 'One', lights: '8', doors: '7' } { _id: 2, name: 'Two', switches: '2' } { _id: 3, name: 'Three', windows: '8', color: 'blue' }
完全符合你的期望!
内容的提问来源于stack exchange,提问作者squinlan
相关产品推荐
相关产品推荐

