Node.js 为什么在mongoose中对字段更新运行验证?

Node.js 为什么在mongoose中对字段更新运行验证?,node.js,mongodb,mongoose,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;

我知道不应该对字段更新进行任何验证,但当我尝试迁移数据库时,它仍然会运行

迁移的一部分:

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`
  }
}
“验证错误:用户验证失败:电子邮件:电子邮件guest1@ex.com已拍摄“

验证是中间件。默认情况下,Mongoose将验证注册为每个模式上的pre('save')钩子

updateOne不会触发保存挂钩。

验证是中间件。默认情况下,Mongoose将验证注册为每个模式上的pre('save')钩子


updateOne不会触发save hook。

您做得对,因为:

save()函数通常是使用Mongoose更新文档的正确方法。使用save(),您可以获得完整的验证和中间件

但是,当您调用
.save()
函数时,将调用所有验证器,包括您的用户电子邮件验证器:

validator: email => User.doesntExist({ email })

在您的情况下,这是一个问题,因为正在验证的用户已经保存在数据库中。。。因此,为了避免这种情况,您需要使用该功能来更新您的用户。

您做得对,因为:

save()函数通常是使用Mongoose更新文档的正确方法。使用save(),您可以获得完整的验证和中间件

但是,当您调用
.save()
函数时,将调用所有验证器,包括您的用户电子邮件验证器:

validator: email => User.doesntExist({ email })

在您的情况下,这是一个问题,因为正在验证的用户已经保存在数据库中。。。因此,为了避免这种情况,您需要使用该函数来更新您的用户。

在mongoose
save()
中有一个选项用于禁用validator以启动它,即
validateBeforeSave
。(自mongoose版本4.4.2起)


因此,如果您想继续使用
save()
而不是
update()
,请尝试使用
save({validateBeforeSave:false})
,在mongoose
save()
中有一个选项可以禁用要激发的验证器,即
validateBeforeSave
。(自mongoose版本4.4.2起)

因此,如果您想继续使用
save()
而不是
update()

doc,请尝试使用
save({validateBeforeSave:false})