【问题标题】:How to do field validations in a mongoose schema based on other fields in the same schema?如何根据同一模式中的其他字段在猫鼬模式中进行字段验证?
【发布时间】:2021-02-23 20:49:14
【问题描述】:

假设我们有:

const mealSchema = Schema({
  _id: Schema.Types.ObjectId,
  title: { type: string, required: true },
  sauce: { type: string }
});

如果title === "Pasta" ,我们如何使sauce 成为强制性的? 验证也需要更新。

我知道解决方法是

  1. 查找
  2. 手动更新
  3. 然后保存

但风险在于,如果我添加一个新属性(比如“价格”),我也会忘记在解决方法中手动更新它。

【问题讨论】:

标签: node.js mongodb mongoose mongodb-query mongoose-schema


【解决方案1】:

文档验证器

Mongoose 有几个内置的验证器。

  • 所有 SchemaType 都具有内置的必需验证器。所需的验证器使用 SchemaType 的 checkRequired() 函数来确定值是否满足所需的验证器。

  • 数字有最小和最大验证器。

  • 字符串具有枚举、匹配、最小长度和最大长度验证器。

对于你的情况,你可以做这样的事情

const mealSchema = Schema({
 _id: Schema.Types.ObjectId, 
title: { type: string, required: true }, 
sauce: { 
      type: string, 
      required: function() { 
        return this.title === "pasta"? true:false ; 
        }
  } 
});

如果内置验证器不够用,您可以定义自定义验证器以满足您的需求。

自定义验证是通过传递一个验证函数来声明的。您可以在SchemaType#validate() 中找到有关如何执行此操作的详细说明。

更新验证器

this 是指使用文档验证时正在验证的文档。但是,在运行更新验证器时,正在更新的文档可能不在服务器的内存中,因此默认情况下,this 的值未定义。那么,有什么办法呢?

context 选项可让您将更新验证器中 this 的值设置为基础查询。

在你的情况下,我们可以这样做:

const mealSchema = Schema({
 _id: Schema.Types.ObjectId, 
title: { type: string, required: true }, 
sauce: { type: string, required: true } 
});

mealSchema.path('sauce').validate(function(value) {
 // When running update validators with
 // the `context` option set to 'query', 
 // `this` refers to the query object. 

if (this.getUpdate().$set.title==="pasta") {
 return  true
}else{
 return false;
}
 }); 

const meal = db.model('Meal', mealSchema);

const update = { title:'pasta', sauce:false};

 // Note the context option 

const opts = { runValidators: true, context: 'query' }; 

meal.updateOne({}, update, opts, function(error) { assert.ok(error.errors['title']); });


不确定这是否能回答您的问题。希望这能为您的最终解决方案增加一些价值。

尚未测试,如果此解决方案需要升级,请提出修改建议。

希望这会有所帮助。

【讨论】:

  • 不幸的是,您的解决方案适用于 save() 但不适用于更新,因为“this”未定义
  • @Gabriel,也解决了更新部分,希望对您有所帮助。
  • 我复制/粘贴了您的代码,但未执行验证。总是需要酱汁。我将 console.log 放入验证功能中,但没有打印任何内容:/
  • 请在此处查看文档...mongoosejs.com/docs/validation.html....and 当您找到正确的解决方案时,请编辑此答案中的代码。顺便说一句,答案中编写的代码是文档中提到的代码的确切模板,我强烈建议您查看文档,我肯定您会在那里解决您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-08
  • 2021-09-12
  • 2015-04-11
  • 2021-07-22
  • 2019-06-16
  • 2017-02-27
相关资源
最近更新 更多