Mongoose - 删除子文档数组项

its*_*sme 8 javascript mongoose mongodb node.js mongodb-query

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

{
 username: String,
 contacts: Array
}
Run Code Online (Sandbox Code Playgroud)

例如,某些用户的联系人将如下所示:

{
 username: "user",
 contacts: [{'id': ObjectId('525.....etc'), 'approved': false}, {'id':ObjectId('534.....etc'), 'approved': true}]
}
Run Code Online (Sandbox Code Playgroud)

现在我需要从联系人中删除一个项目,所以我这样做:

model.findByIdAndUpdate(23, {'$pull': {
              'contacts':{'id':'525.....etc'}
              }});
Run Code Online (Sandbox Code Playgroud)

但似乎没有工作,没有错误,但它没有被删除,我只是想为用户返回此文档:

{
     username: "user",
     contacts: [{'id':ObjectId('534.....etc'), 'approved': false}]
    }
Run Code Online (Sandbox Code Playgroud)

怎么实现这个?

Nei*_*unn 12

$pull操作者实际上只是执行在其上操作所述阵列元件上的条件.看起来您的问题可能实际上并未表明您可能正在使用ObjectIdmongoose默认为所有数组字段创建的值.

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

model.findByIdAndUpdate(23, {
    '$pull': {
        'contacts':{ '_id': new ObjectId(someStringValue) }
    }
});
Run Code Online (Sandbox Code Playgroud)

或者实际上你可以更好地定义你的"模式",而mongoose实际上会根据模式中定义的"类型"为你"自动"对象ID:

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

var userSchema = new Schema({
    username: String,
    contacts: [contactSchema]
});
Run Code Online (Sandbox Code Playgroud)

这允许猫鼬为严格类型的字段定义"遵循规则".所以现在它知道你实际上有一个_id字段用于contacts数组的每个元素,并且该字段的"type"实际上是一个字段,ObjectId因此它将自动重新提供作为真正的ObjectId提供的"String"值.