【问题标题】:Skip or Disable validation for mongoose model save() call跳过或禁用猫鼬模型 save() 调用的验证
【发布时间】:2015-01-27 17:39:29
【问题描述】:

我希望创建一个保存到 MongoDB 的新文档,无论它是否有效。我只想在模型保存调用时暂时跳过猫鼬验证。

在我导入 CSV 的情况下,CSV 文件中不包含一些必填字段,尤其是其他文档的参考字段。然后,以下示例未通过 mongoose 验证所需检查:

var product = mongoose.model("Product", Schema({
    name: {
        type: String,
        required: true
    },
    price: {
        type: Number,
        required: true,
        default: 0
    },
    supplier: {
        type: Schema.Types.ObjectId,
        ref: "Supplier",
        required: true,
        default: {}
    }
}));

var data = {
    name: 'Test',
    price: 99
}; // this may be array of documents either

product(data).save(function(err) {
  if (err) throw err;
});

是否可以让 Mongoose 知道在 save() 调用中不执行验证?

[编辑]

我也尝试了Model.create(),但它也调用了验证过程。

【问题讨论】:

    标签: node.js mongodb validation mongoose


    【解决方案1】:

    支持since v4.4.2:

    doc.save({ validateBeforeSave: false });
    

    【讨论】:

      【解决方案2】:

      虽然可能有一种方法可以禁用验证,但我不知道您的一个选项是使用不使用中间件的方法(因此没有验证)。其中之一是insert,它直接访问 Mongo 驱动程序。

      Product.collection.insert({
        item: "ABC1",
        details: {
          model: "14Q3",
          manufacturer: "XYZ Company"
        },
      
      }, function(err, doc) {
        console.log(err);
        console.log(doc);
      });
      

      【讨论】:

      • 谢谢,但我没有conditions 到findOneAndUpdate。这将只是纯插入。其他方法呢?
      • @Sithu - 我添加了一个使用 insert 的示例,这是另一种驱动方法。
      • 它似乎有效并且被赞成,但我收到了错误CastError: Cast to ObjectId failed for value...。根据我更新的示例,错误似乎指向supplier 字段,尽管我有一个默认值。抱歉,我是 mongodb 和 mongoose 的新手。
      • 嗯...我觉得这里没有体现 Mongoose 模式的默认值,因为我们是直接使用 Mongo 方法?
      • 可能是这样 - 使用直接驱动程序方法将绕过所有 Mongoose,例如验证、getter、setter 等。不过,我会问自己的问题是,为什么您基本上有一个可选的必填字段.您可能希望删除所需的调用并以其他方式处理它。您可以编写一个验证函数,该函数可以根据您在某处设置的标志(即它是否是 csv 上传)来检查是否存在。 mongoosejs.com/docs/validation.html
      【解决方案3】:

      您可以拥有多个使用同一个集合的模型,因此请创建第二个没有所需字段约束的模型以用于 CSV 导入:

      var rawProduct = mongoose.model("RawProduct", Schema({
          name: String,
          price: Number
      }), 'products');
      

      model 的第三个参数提供了一个明确的集合名称,允许您让这个模型也使用products 集合。

      【讨论】:

      • 嗯,您的回答相当可观,但是根据我们的应用程序结构,架构是在一个地方定义的。因此,这可能会导致重复的架构定义。
      【解决方案4】:

      通过替换 validate 方法,我能够忽略验证并保留中间件行为:

      schema.method('saveWithoutValidation', function(next) {
          var defaultValidate = this.validate;
          this.validate = function(next) {next();};
      
          var self = this;
          this.save(function(err, doc, numberAffected) {
              self.validate = defaultValidate;
              next(err, doc, numberAffected);
          });
      });
      

      我只用 mongoose 3.8.23 测试过

      【讨论】:

        【解决方案5】:
        1. 架构配置 validateBeforeSave=false
        2. 使用验证方法

        // define
        
        var GiftSchema = new mongoose.Schema({
            name: {type: String, required: true},
            image: {type: String}
        },{validateBeforeSave:false});
        
        
        
        // use 
        var it new Gift({...});
        it.validate(function(err){
                if (err) next(err)
                else it.save(function (err, model) {
                    ...
                });
            })

        【讨论】:

          猜你喜欢
          • 2014-08-21
          • 2018-03-05
          • 2016-01-23
          • 1970-01-01
          • 2017-04-04
          • 2017-06-30
          • 2017-08-24
          • 2021-12-18
          • 1970-01-01
          相关资源
          最近更新 更多