采用mongoose中定义的一个简单模式,如下所示:
const Person = new Schema({
username: {
type: String,
index: true,
},
roles: [{
type: Schema.Types.ObjectId,
ref: 'Role',
required: [true,
'Role is required'],
}],
})
当您在不提供至少一个角色的情况下保存新记录时,MongoDB将抛出一个需要角色的错误。
我有另一段代码,您可以在其中更新(添加或删除(角色数组中的角色。但是,我可以使用下面的代码段删除所有角色。
Person.findOneAndUpdate({_id: 'some id'}, {
$pull: {
roles: {
$in: [...list of ids,]
}
}
}, {new: true}).populate('roles').exec()
假设我列出了那个人的所有角色,我会删除它们,让那个人没有角色。
我如何强制执行早先的要求,即角色是必需的?有没有一个简单的破解,或者我应该写一段代码来验证这个删除并自己强制执行?
之所以能够删除所有角色,并且所需的验证不起作用,是因为验证是作为Mongoose中的内部中间件实现的,中间件在更新过程中不会执行。你可以在这里阅读更多关于它的信息。
如果使用MongoDB 4.0或更高版本,则可以在update
调用中使用runValidators: true
选项。您可以在Mongoose更新验证器文档中阅读更多关于runValidators选项的信息。
你可以试试下面的代码(我还没有测试过(:
Person.findOneAndUpdate({_id: 'some id'}, {
$pull: {
roles: {
$in: [...list of ids,]
}
}
}, {new: true, runValidators: true}).populate('roles').exec()
根据Mongoose官方文档,更新验证器的工作以下运营商(以及MongoDB versoins(:
- $set
- $unset
- $push(>=4.8.0(
- $addToSet(>=4.8.0(
- $pull(>=4.12.0(
- $pullAll(>=4.12.0(
或者您还可以为findOneAndUpdate
、设置Pre
挂钩
// Pre hook for `findOneAndUpdate`
ClientSchema.pre('findOneAndUpdate', function(next) {
this.options.runValidators = true;
next();
});
如果您有MongoDB<4.0
然后,您可以使用.findOne()
查找文档,在文档中设置新属性,然后尝试使用.save()
再次保存它。这应该运行验证。