Mongoose - 删除子文档数组项

时间:2014-10-08 08:40:55

标签: javascript node.js mongodb mongoose mongodb-query

我为用户提供了这个小模式:

{
 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 个答案:

答案 0 :(得分:11)

$pull运算符实际上只是在运行它的数组元素上执行条件。您的问题似乎并未真正表明您可能正在使用mongoose默认为所有数组字段创建的ObjectId值。

因此,在导入ObjectId创建方法后,您可以像这样查询:

model.findByIdAndUpdate(23, {
    '$pull': {
        'contacts':{ '_id': new ObjectId(someStringValue) }
    }
});

或者实际上你可以实际定义你的"架构"好一点,猫鼬实际上会自动#34; autocast"你的ObjectId基于"类型"在架构中定义:

var contactSchema = new Schema({
    approved: Boolean
});

var userSchema = new Schema({
    username: String,
    contacts: [contactSchema]
});

这允许猫鼬遵守规则"对于严格类型的字段定义。所以现在它知道你实际上有一个_id字段用于contacts数组的每个元素,而#34; type"该字段实际上是ObjectId,因此它会自动重新播放"字符串"作为真正的ObjectId提供的值。