Mongoose - 删除子文档数组项
Posted
技术标签:
【中文标题】Mongoose - 删除子文档数组项【英文标题】:Mongoose - delete subdocument array item 【发布时间】:2014-12-02 20:35:10 【问题描述】:我有这个供用户使用的小架构:
username: String,
contacts: Array
例如,某些用户的联系人将如下所示:
username: "user",
contacts: ['id': ObjectId('525.....etc'), 'approved': false, 'id':ObjectId('534.....etc'), 'approved': true]
现在我需要从联系人中删除一个项目,所以我这样做:
model.findByIdAndUpdate(23, '$pull':
'contacts':'id':'525.....etc'
);
但似乎不起作用,没有错误,但它没有被删除,我只是想为用户返回这个文档:
username: "user",
contacts: ['id':ObjectId('534.....etc'), 'approved': false]
如何做到这一点?
【问题讨论】:
【参考方案1】:$pull
运算符实际上只是对它所操作的数组元素执行条件。看来您的问题实际上可能并未表明您可能正在使用 mongoose 默认为所有数组字段创建的 ObjectId
值。
因此,在导入 ObjectId
创建方法后,您可以这样查询:
model.findByIdAndUpdate(23,
'$pull':
'contacts': '_id': new ObjectId(someStringValue)
);
或者实际上你可以更好地定义你的“模式”,猫鼬实际上会根据模式中定义的“类型”为你“自动转换”ObjectId:
var contactSchema = new Schema(
approved: Boolean
);
var userSchema = new Schema(
username: String,
contacts: [contactSchema]
);
这允许 mongoose 为严格类型的字段定义“遵循规则”。所以现在它知道你实际上为contacts数组的每个元素都有一个_id
字段,并且该字段的“类型”实际上是一个ObjectId
,所以它会自动重新转换“字符串”值作为真正的 ObjectId 提供。
【讨论】:
嗨,谢谢,但现在我收到了这个错误:[MongoError: exception: cannot use the part (contacts of contacts.id) to traverse the element (contacts: [ id: ObjectId( '543394bb964ac60915ceba8b'), 批准: false , id: ObjectId('543399f9964ac60915ceba8c'), 批准: false ]) 这可能是什么?我用了你的点注释—— @sbaaaang 你到底在做什么?您是否按照您的要求使用“点符号”形式?顺便说一句,感谢您清楚地表明您的实际数据与您发布的方式不同,这可能又是问题的一部分。请编辑以显示您的真实数据结构。 是的,使用 dot notation 就像你说的那样,是的,我正在使用 ObjectIds 但我猜这不是问题:P 不是吗? (已编辑问题) 好的修复了它,因为我发布的问题只需要在查询时包装新的 ObjectId(idContact) ;) 谢谢!请编辑答案,以便我接受它 要明确 model.findByIdAndUpdate(23, '$pull': 'contacts':'id': new ObjectId('525.....etc') ); 工作【参考方案2】:终于!
MongoDB:
"imgs" : "other" : [
"crop" : "../uploads/584251f58148e3150fa5c1a7/photo_2016-11-09_21-38-55.jpg",
"origin" : "../uploads/584251f58148e3150fa5c1a7/o-photo_2016-11-09_21-38-55.jpg",
"_id" : ObjectId("58433bdcf75adf27cb1e8608")
]
,
router.get('/obj/:id', function(req, res)
var id = req.params.id;
Model.findOne('imgs.other._id': id, function (err, result)
result.imgs.other.id(id).remove();
result.save();
);
【讨论】:
以上是关于Mongoose - 删除子文档数组项的主要内容,如果未能解决你的问题,请参考以下文章