如何使用MongoDB Update聚合更新嵌套数组并支持Upsert?
MongoDB 嵌套数组 Upsert 更新方案
针对你的需求,需要处理三种场景:
- 目标category文档不存在:创建新文档,包含对应item对象及带新增数字的sub_list
- 目标category文档存在,但list中无对应item对象:向list添加新的item对象,sub_list包含新增数字
- 目标category文档存在且list中有对应item对象:向该对象的sub_list添加数字(用
$addToSet避免重复,也可换成$push)
原查询条件同时匹配category和list.item会导致场景2触发新文档创建,不符合预期,因此需要调整查询条件为仅匹配category,再用聚合管道实现更新逻辑。以下是完整的语句:
db.collection.update( { "category": "A" }, // 仅按category匹配,确保找到对应文档(不存在则upsert) [ { $set: { list: { $cond: [ // 判断list中是否存在item=1的元素 { $some: { input: "$list", cond: { $eq: ["$$this.item", 1] } } }, // 存在则更新对应sub_list { $map: { input: "$list", as: "elem", in: { $mergeObjects: [ "$$elem", { sub_list: { $cond: [ { $eq: ["$$elem.item", 1] }, { $addToSet: ["$$elem.sub_list", 55] }, // 替换55为你要添加的数字 "$$elem.sub_list" ] } } ] } } }, // 不存在则向list添加新对象 { $concatArrays: [ { $ifNull: ["$list", []] }, [{ item: 1, sub_list: [55] }] // 替换55为你要添加的数字 ] } ] } } } ], { upsert: true } )
关键说明:
- 使用聚合管道作为更新操作,能灵活处理数组的条件判断与修改
$some用于检测list中是否存在目标item$map遍历list,仅更新匹配item的对象的sub_list$concatArrays在list无目标item时,追加新的item对象$addToSet确保sub_list中不重复添加数字,若允许重复可替换为$push- 当category文档不存在时,
upsert: true会自动创建包含指定list结构的新文档
内容的提问来源于stack exchange,提问作者Manas R. Makde
相关产品推荐
相关产品推荐

