Mongoose: Schema.type.Mixed and deep modification does not update document

Created on 11 Sep 2013  路  16Comments  路  Source: Automattic/mongoose

When I try to update a deep nested field, the query is well sent to MongoDB but when I do a find on this doc, the field is not updated.

Example

var DtSchema = mongoose.Schema({
     nested : Schema.type.mixed
});

var Dt = mongoose.model('Dt', DtSchema)

var test = new Dt({nested : { a : 'test', b : { c : { d : null } } } });

test.save(function(err, _test) {
    _test.nested.b.c.d = 'Hello !';
    _test.save(function(err, _test) {
       // _test is okay, the field nested.b.c.d is updated 

       Dt.findOne({_id : _test._id}, function(err, doc) {
           // Here The doc has not the nested.b.c.d field updated
       });
    })
});

Most helpful comment

Did you guys try using markModified()? Mixed types won't save updates unless you tell Mongoose something has changed

All 16 comments

did you figure this out? I'm having the same issue. Deep nested fields do not update for me but shallow fields do.

@milesingrams which version of mongoose and mongodb are you using?

@vkarpov15 I have the same issue, running MongoDB 2.4.9 32-bit and Mongoose 3.5.16.

I've been working around it by using a findOneAndUpdate call and explicitly rebuilding the whole nested object in the update params.

Same here. Basically, I need to be doing this:

File.findOneAndUpdate({ _id: file._id.toString() }, _.omit(file.toJSON(), [ '_id', '__v' ]), {}, done);

Instead of:

file.save(done);

Running Mongoose 3.8.12 and mongodb-win32-x86_64-2.2.3 both on Win7 x64.

Same problem here. It should at least throw an error!!! Because it works for certain type of objects I pass. If the property that I'm updating looks like the following, it updates every time:

{
msgIds: {
"uuid": [1234, 4567]
}
}

if the object I'm setting is just the following, it never updates.

{ msgIds:{} }

It doesn't throw an error, the only thing that I know is that it tells me that there is no records updated. I tried using .update and .findByIdAndUpdate.

Did you guys try using markModified()? Mixed types won't save updates unless you tell Mongoose something has changed

I just tried markModified and .save but it removed the property after the update. I'm currently trying changing the internal structure of the data to avoid nesting and figure out if it works. I'll try to put together an example but this seems to me to be mongo/mongoose not behaving as it should. It should throw some kind of warning.

i just tried markModified and .save as well and it solved the problem for me. Really should throw a warning or actually just save.. whats the reasoning behind it ignoring/not detecting the change?

markModified works well for me, with "mongoose": "~3.8.14" on Mac os.

Thanks, markModified is really useful in this case.

what about 1 level further, markModified didn't work in my case:
mongoose scheme:

var restsSchema = new Schema({
    name: String,
    menu: mongoose.Schema.Types.Mixed
});

simplfied document:

{
    name: "Dominos Pizza",
    menu:{
             "1":{
                  name: "Plain Pizza",
                  soldCounter: 0
               },
             "2":{
                  name: "Pizza with vegetables",
                  soldCounter: 0
                }
         }
}

I'm trying to update the soldCounter when given a single/array of menu items as followed:

function(course, rest){
        rest.markModified("menu.1");
        db.model('rests').update({_id: rest._id},{$inc:{"menu.1.soldCounter":1}});

once this will work i obviously will want to make it more generic, something like: (this syntax is not working)

function(course, rest){
        rest.markModified("menu." + course.id);
        db.model('rests').update({_id: rest._id},{$inc:{"menu.+"course.id"+.soldCounter":1}});

any one can help with this one?

Why are you using markModified() with update()? Those two don't have anything to do with each other.

Nothing from the functions above will work, but I wanted it to clear what I'm trying to achieve.

I also have no problem changing the scheme so that 'menu' will be an indexed array of types.Mixed

markModified() causes this: VersionError: No matching document found.

If you do this, it will work.

var nested = JSON.parse(JSON.stringify(_test.nested));
//now changed the nested object.
nested.a = "new value"
_test.nested = nested;
_test.save();

@bhagaban Thank you so much! Just when I thought I had tried everything. Your code worked wonderfully.

Was this page helpful?
0 / 5 - 0 ratings