如何在MongoDB中移除嵌套对象数组中的属性?
移除MongoDB嵌套对象数组中的指定属性
你的reply是多层递归嵌套的数组,普通$unset仅能处理固定层级的属性,无法覆盖所有嵌套子数组,因此需要通过递归方式处理每一层的reply元素。
方法1:递归处理任意层级嵌套数组(推荐)
借助MongoDB 4.4+支持的$function自定义递归函数,遍历所有嵌套reply数组并移除tag属性:
db.collection.aggregate([ { $addFields: { reply: { $function: { body: function(replyArray) { const removeTag = arr => { return arr.map(item => { // 删除当前元素的tag属性 delete item.tag; // 递归处理子级reply数组 if (item.reply && Array.isArray(item.reply)) { item.reply = removeTag(item.reply); } return item; }); }; return removeTag(replyArray); }, args: ["$reply"], lang: "js" } } } }, // 按需保留文档字段,无需额外过滤可省略此阶段 { $project: { _id: 1, name: 1, description: 1, reply: 1 } } ])
方法2:处理固定层级的嵌套数组
若嵌套层级固定(例如最多2层),可通过$map逐层定义保留字段,间接移除tag:
db.collection.aggregate([ { $project: { _id: 1, name: 1, description: 1, reply: { $map: { input: "$reply", as: "topReply", in: { _id: "$$topReply._id", name: "$$topReply.name", description: "$$topReply.description", reply: { $map: { input: "$$topReply.reply", as: "subReply", in: { _id: "$$subReply._id", name: "$$subReply.name", description: "$$subReply.description", reply: "$$subReply.reply" } } } } } } } } ])
普通$unset失效原因
若你尝试过$unset: "reply.tag",该路径仅能匹配顶层reply数组元素的tag属性,无法覆盖嵌套在reply.reply中的子元素,因此子数组内的tag会被保留,导致操作未达到预期效果。
内容的提问来源于stack exchange,提问作者Epple
相关产品推荐
相关产品推荐

