Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose: Is it possible to set strict:false after defining the schema, like through a middleware or a plugin?

When you define a schema in Mongoose you have an option to set {strict:false}

Is there an option to have that set after you've defined the schema? Like through a mongoose middleware or a mongoose plugin?

I want to create a plugin which will need to store some additional data into the database, which I wouldn't be able to unless the plugin user has either set {strict:false} or added the fields that I would want to store data in their schema themselves, both of which are unlikely. So I was wondering if there's a way for me to make that happen from my plugin code itself?

like image 312
laggingreflex Avatar asked Oct 14 '25 03:10

laggingreflex


3 Answers

Mongoose is an ODM, and the {strict: true} option in this regard only applies to queries you run through Mongoose, it's not enforced in the mongoDB side, your documents remain schemaless.

But you don't have to use mongoose to make all of your queries, you can use the native mongoDB driver underneath in order to bypass all of that. Mongoose even gives you a shortcut to do so in the form of Model.collection. Here's an example:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var PersonSchema = new Schema({
    name: String
}, {
    strict: true
});

var Person = mongoose.model('Person', PersonSchema);

mongoose.connect('mongodb://localhost/test', function(err) {
    if (err) {
        throw err;
    }

    Person.collection.insert({
        name: 'Bill',
        extraProp: 'Hello World'
    }, function(err, result) {
            if (err) {
                throw err;
            }
            console.log(result);
        });
    console.log('Connected');
});

Edit:

You can disable strict for specific model paths. I think this is more what you're looking for.

PersonSchema.pre('save', function(next) {
    this.set('extraProp', 'hello', {
        strict: false
    });
    next();
});
like image 177
Andrew Lavers Avatar answered Oct 16 '25 18:10

Andrew Lavers


Just an FYI, what I ended up doing was creating a sub-schema, then disabling strict in there..

I was doing this for meta data, which is unstructured, so heres my example:

module.exports = Mongoose => {
    const Schema = Mongoose.Schema

    const metaSchema = new Schema({},{ strict: false })

    const modelSchema = new Schema({
        title: Schema.Types.String,
        metaData: metaSchema
    })

    modelSchema.statics.createMeta = function( title, meta, cb ) {
        return new this({
            title: title,
            metaData: meta
        }).save()
    }

    return Mongoose.model( 'Foobar', modelSchema )
}

Then to use it:

Foobar.createMeta( 'blah blah', {
    foo: 'AA',
    bar: 'BB'
} )
    .then( data =>  console.log( '# RESULT:', data ) )
    .catch( err => console.error( 'ERROR:',err ) )

Which seems to work fine :)

like image 22
Justin Avatar answered Oct 16 '25 18:10

Justin


Mongoose is an ODM, and the {strict: true} option in this regard only applies to queries you run through Mongoose, it's not enforced in the mongoDB side, your documents remain schemaless.

But you don't have to use mongoose to make all of your queries, you can use the native mongoDB driver underneath in order to bypass all of that. Mongoose even gives you a shortcut to do so in the form of Model.collection. Here's an example:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var PersonSchema = new Schema({
    name: String
}, {
    strict: true
});

var Person = mongoose.model('Person', PersonSchema);

mongoose.connect('mongodb://localhost/test', function(err) {
    if (err) {
        throw err;
    }

    Person.collection.insert({
        name: 'Bill',
        extraProp: 'Hello World'
    }, function(err, result) {
            if (err) {
                throw err;
            }
            console.log(result);
        });
    console.log('Connected');
});

Edit:

You can disable strict for specific model paths. I think this is more what you're looking for.

PersonSchema.pre('save', function(next) {
    this.set('extraProp', 'hello', {
        strict: false
    });
    next();
});
like image 40
Andrew Lavers Avatar answered Oct 16 '25 16:10

Andrew Lavers