MongoDB如何从双层嵌套数组中按_id移除指定对象
用MongoDB的$pull移除双层嵌套数组中的指定对象
需求:从用户文档的双层嵌套数组中移除指定任务,必须通过**_id**查找(任务顺序不固定,不能用数组索引或taskName)。
示例用户文档:
const user = { address: '123 example road', age: 23, taskSets: [ { _id: '649376ee6d1efd215999881a', name: 'Cleaning', tasks: [ { _id: '649316ee6d1efd215829882b', taskName: 'kitchen', }, { _id: '649316f16d1efd2139998884', taskName: 'living_room', } ] }, { _id: '649316ee3d1efd285999882d', name: 'Mail', tasks: [ { _id: '1234', taskName: 'deliver', } ] } ] }
当前尝试的代码无法生效:
await db.models.Users.findOneAndUpdate( { _id: Types.ObjectId(userId) }, { $pull: { "taskSets.$[i].tasks.$[j]._id": taskId } }, { new: true, arrayFilters: [ { "i._id": Types.ObjectId(taskSetId) }, { "j._id": Types.ObjectId(taskId) } ] } );
问题原因
你写错了$pull的目标路径:"taskSets.$[i].tasks.$[j]._id" 不是正确的用法,$pull需要直接作用于要修改的数组(也就是tasks),并指定要移除元素的匹配条件,而非指向数组元素的某个字段。
正确代码
await db.models.Users.findOneAndUpdate( { _id: Types.ObjectId(userId) }, { // 针对匹配到的taskSet下的tasks数组,移除_id符合条件的元素 $pull: { "taskSets.$[i].tasks": { _id: Types.ObjectId(taskId) } } }, { new: true, // 只需要一个数组过滤器定位到目标taskSet arrayFilters: [ { "i._id": Types.ObjectId(taskSetId) } ] } );
说明
- 数组过滤器
{ "i._id": Types.ObjectId(taskSetId) }用来精准定位到要修改的taskSets元素 - $pull直接作用于该taskSet下的
tasks数组,通过_id匹配要移除的任务对象,无需依赖数组顺序 new: true确保返回修改后的最新文档
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

