如何基于同一模式中的其他字段在猫鼬模式中进行字段验证?

时间:2020-11-11 20:49:22

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

让我们说:

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

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

我知道一种解决方法

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

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

1 个答案:

答案 0 :(得分:0)

文档验证器

猫鼬有几个内置的验证器。

  • 所有SchemaTypes都具有内置的验证器。所需的验证器使用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的值。那么,有什么解决方案?

上下文选项使您可以将更新验证器中的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']); });


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

还没有测试过,如果此解决方案需要升级,请提出修改建议。

希望这会有所帮助。