MongoDB如何为多层嵌套数组中的Inventory数组新增UOM字段
问题原因
之前的操作没有生效有两个核心原因:
aggregate聚合操作默认仅对查询结果做计算返回,不会直接修改集合中持久化存储的原始数据ParentType.Inventory是数组类型,直接通过ParentType.Inventory.UOM的点语法赋值,不符合MongoDB嵌套数组的操作规则,既无法给数组内的每个元素追加字段,还会破坏原有数组结构。
现有Concession集合的原始数据结构如下:
{ "ParentType": { "Food": [ { "Name": "Burger", "FoodId": "5e3abe145c1bfb31b4e335de", "Price": 0, "Quantity": 1, "SubCategory": 0 } ], "Inventory": [ { "Name": "Small Popcorn", "InventoryId": "5e3a64245c1bfb31b4e335b7", "Price": 0, "Quantity": 1, "SubCategory": 0 } ] } }
需求为仅向ParentType下的Inventory数组的所有元素新增UOM字段,不改动Food数组的任何内容。
正确实现方案
持久化修改集合原始数据(推荐)
适用于MongoDB 4.2及以上版本(支持聚合管道作为更新参数),直接执行updateMany语句批量更新所有符合条件的文档:
db.Concession.updateMany( // 过滤条件:仅更新存在ParentType.Inventory数组的文档 { "ParentType.Inventory": { $exists: true, $type: "array" } }, [ { $set: { "ParentType.Inventory": { // 遍历Inventory数组的每一个元素 $map: { input: "$ParentType.Inventory", as: "invItem", in: { // 保留元素原有所有字段,追加UOM字段 $mergeObjects: ["$$invItem", { UOM: null }] } } } } } ] )
说明:如果你需要
UOM字段存储字符串值"null"而非空值null,把代码里{ UOM: null }改成{ UOM: "null" }即可。语句不会改动ParentType.Food下的任何内容。
仅临时查询返回带UOM字段的结果(不修改原数据)
如果不需要修改原集合存储的数据,只是想查询时返回追加了UOM字段的结果,使用修正后的聚合语句即可:
db.Concession.aggregate([ { $addFields: { "ParentType.Inventory": { $map: { input: "$ParentType.Inventory", as: "invItem", in: { $mergeObjects: ["$$invItem", { UOM: null }] } } } } } ])
内容的提问来源于stack exchange,提问作者Daffodil s
相关产品推荐
相关产品推荐

