为什么验证要在猫鼬的字段更新中进行?

时间:2019-03-24 20:33:55

标签: node.js mongodb mongoose

我知道不应对字段更新进行任何验证,但是无论如何,当我尝试迁移数据库时,它都会运行。

部分迁移:

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已被占用”

3 个答案:

答案 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不会触发保存钩子。

相关问题