Mongoose: document.save doesn't work with Schema.Types.Mixed

Created on 13 Aug 2014  路  7Comments  路  Source: Automattic/mongoose

When a document is modified inside a Schema.Types.Mixed SchemaType the change is ignored in updates with the document.save function:

var mongoose    = require('mongoose');

mongoose.connect('mongodb://localhost');


var schema1 = new mongoose.Schema({
    "number": Number,
    "mixed": mongoose.Schema.Types.Mixed
}, {
  'strict': true
});

var Model = mongoose.model('mixed', schema1);

var document = new Model({ "number": 1, "mixed": { "number": 1 } })

document.save(function(e, r, n){
    if(e) throw e;

    console.log("Inserted document? " + Boolean(n));

    document.number = 2;

    document.save(function(e, r, n){
        if(e) throw e;

        console.log("Updated number field? " + Boolean(n));

        document.mixed.number = 2;

        document.save(function(e, r, n){
            if(e) throw e;

            console.log("Updated mixed.number field? " + Boolean(n));
        });
    });
});


This script will print the following:

Inserted document? true
Updated number field? true
Updated mixed.number field? false

Most helpful comment

Right now you need to call markModified on the mixed path, see docs. Unfortunately I don't think this is going to change soon, we've got a lot of work going for 3.9/4.0.

All 7 comments

Right now you need to call markModified on the mixed path, see docs. Unfortunately I don't think this is going to change soon, we've got a lot of work going for 3.9/4.0.

Thank you. I should have digged more in the documentation. It would be lovely see a change in the future, It's pretty contraintuitive right now IMO.

@brunoduran I agree, this isn't particularly great, but its just not a priority for the next few months. Will re-address this later.

Was this ever re-addressed?

@kyleshrader nope. Outside of proxies, it isn't really possible for us to do change tracking for mixed docs.

+1, this tripped me up for a bit, first few hours of ever using mongoose and I tracked my woes down to this, I just happen to have many Mixed types due to polymorphic records

const UnitSchema = {
    id: Number,
    type: Number,
    stats: [ Schema.Types.Mixed ],
    storage: [ Schema.Types.Mixed ],
    descriptor: Schema.Types.Mixed
}

is there a clean way create arbitrary fields without using Schema.Types.Mixed and adding a bunch of markModified calls? I've worked around a few by using { _id: false, foo: Number, .. } but I can't seem to avoid their usage in, ie. the descriptor field in the aforementioned schema.

@bsdunx no not currently. You can also use .set() manually, like unit.set('descriptor.foo', 'bar') as a replacement for unit.descriptor.foo = 'bar';, that way you won't have to use markModified()

Was this page helpful?
0 / 5 - 0 ratings