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
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()
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.