我知道不应对字段更新进行任何验证,但是无论如何,当我尝试迁移数据库时,它都会运行。
部分迁移:
const arr = await User.find({ ban: { $exists: true } });
arr.forEach(async item => {
// this works
// await User.updateOne({ _id: item._id }, { ban: false });
// this doesn't
item.ban = false;
await item.save();
});
部分架构:
email: {
type: String,
validate: {
validator: email => User.doesntExist({ email }),
message: ({ value }) => `Email ${value} has already been taken`
}
}
“ ValidationError:用户验证失败:电子邮件:电子邮件guest1@ex.com已被占用”
答案 0 :(得分:1)
您做对了,因为reported in mongoose documentation:
save()函数通常是使用Mongoose更新文档的正确方法。使用save(),您可以获得完整的验证和中间件。
但是,当您调用.save()
函数时,将调用所有验证器,包括您的用户电子邮件验证器:
validator: email => User.doesntExist({ email })
在您的情况下,这是一个问题,因为正在验证的用户已经保存在数据库中了。因此,要避免这种情况,您需要使用.update()函数来更新用户。 / p>
答案 1 :(得分:1)
有一个选项可禁用以猫鼬save()
(即validateBeforeSave
)触发的验证器。 (从猫鼬版本4.4.2开始)
因此,如果您想继续使用save({ validateBeforeSave: false })
而不是save()
,请尝试使用update()
。
答案 2 :(得分:0)
https://mongoosejs.com/docs/validation.html#validation
验证是中间件。猫鼬默认将验证注册为每个模式上的pre('save')钩子。
updateOne不会触发保存钩子。