Skip or Disable validation for mongoose model save() call

13,778

Solution 1

Though there may be a way to disable validation that I am not aware of one of your options is to use methods that do not use middleware (and hence no validation). One of these is insert which accesses the Mongo driver directly.

Product.collection.insert({
  item: "ABC1",
  details: {
    model: "14Q3",
    manufacturer: "XYZ Company"
  },

}, function(err, doc) {
  console.log(err);
  console.log(doc);
});

Solution 2

This is supported since v4.4.2:

doc.save({ validateBeforeSave: false });

Solution 3

You can have multiple models that use the same collection, so create a second model without the required field constraints for use with CSV import:

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

The third parameter to model provides an explicit collection name, allowing you to have this model also use the products collection.

Solution 4

I was able to ignore validation and preserve the middleware behavior by replacing the validate method:

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);
    });
});

I've tested it only with mongoose 3.8.23

Solution 5

  1. schema config validateBeforeSave=false
  2. use validate methed

// 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) {
            ...
        });
    })

Share:
13,778
Sithu
Author by

Sithu

A passionate software developer based in Yangon, Myanmar (Burma) since 2005, using various languages and technologies such as PHP, Node.js, Rails, Android, Visual FoxPro, MySQL, PostgreSQL, MongoDB, Git, etc. Also spending much time in management, mentoring, coaching and research. Original creator and core developer at PHPLucidFrame. Check out my open source! profile for Sithu on Stack Exchange, a network of free, community-driven Q&A sites http://stackexchange.com/users/flair/887306.png

Updated on June 30, 2022

Comments

  • Sithu
    Sithu almost 2 years

    I'm looking to create a new Document that is saved to the MongoDB regardless of if it is valid. I just want to temporarily skip mongoose validation upon the model save call.

    In my case of CSV import, some required fields are not included in the CSV file, especially the reference fields to the other document. Then, the mongoose validation required check is not passed for the following example:

    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;
    });
    

    Is it possible to let Mongoose know to not execute validation in the save() call?

    [Edit]

    I alternatively tried Model.create(), but it invokes the validation process too.

  • Sithu
    Sithu over 9 years
    Thanks, but I have no conditions to findOneAndUpdate. It will be just pure insert. What about other methods?
  • Sithu
    Sithu over 9 years
    Well, your answer is quite considerable, but according to our application structure, schema are defined in one place. So, this could lead to the duplicate schema definition.
  • cyberwombat
    cyberwombat over 9 years
    @Sithu - I have added an example using insert which is another one of the driver methods.
  • Sithu
    Sithu over 9 years
    It seems working and upvoted, but I got the error CastError: Cast to ObjectId failed for value.... According to my updated example, the error seems pointing to the supplier field although I have a default value. Sorry, I'm new to mongodb and mongoose.
  • Sithu
    Sithu over 9 years
    Humm...I think the default value of the Mongoose schema is not reflected here because we are using the Mongo method directly?
  • cyberwombat
    cyberwombat over 9 years
    That may be it - using direct driver methods will bypass all of Mongoose such as validation, getters, setters, etc.. The thing that I would ask myself though is why you have essentially an optional required field. You may want to remove that required call and handle it in an other way. You could write a validation function that can check for existence based on say a flag that you set somewhere (i.e. is it a csv upload). mongoosejs.com/docs/validation.html
  • Sithu
    Sithu over 9 years
    It would be required in the other side, e.g., product creation, but it may be optional in this CSV import.
  • cyberwombat
    cyberwombat over 9 years
    Then I would explore handling this in a mongoose validation function.
  • Sithu
    Sithu over 9 years
    However, I think optional/required is not a case since we are using the driver method directly. If a field is not provided in the data, it should be skip (like the insert query execute in relational database).
  • cyberwombat
    cyberwombat over 9 years
    Well yes - what I am suggesting is either use the driver method and deal with lack of mongoose features or make a validator. One or the other.