Question

I do this after a mongoose .find query:

data2[0].videos[temp].markModified('fakeName');
data2[0].save(function(err,product,numberAffected){
    if(err){
        console.log("error saving manifest")
        console.log(err);
        var back={success:false, reason:err};
        callback(back);
        return;
    }
    if(numberAffected>=1){
        console.log("manifest saved",product.videos[temp]);
        var back={success:true};
        callback(back);
        return;
    }else{
        console.log("nothing saved");
        callback({success:false});
        return;
    }
});

Which prints this:

  manifest saved { fakeName: 'devrenameTest',
  name: 'bkdyZVb--',
  version: 1,
  dateCreated: 1406846165732,
  dateUpdated: 1406846165732,
  vidLoc: '[url removed]',
  thumbLoc: '[url removed]',
  author: '53a47a469c52c9d83a2d71d9',
  _id: 53dac4d533c061dd0b000007,
  sharedWithGroups: [],
  sharedWith: [],
  tags: [] }

So it appears to have worked right?

But then if I look on my database, I see a subdoc inside of videos made up only of one fakeName field, and the object that I was modifying is without a fakeName field.

What's going on?

I changed the first line up there to

data2[0].markModified('videos');

And that seemed to fix it.

I'd still accept answers based on an explanation of what is happening.

Was it helpful?

Solution

Since it is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. To "tell" Mongoose that the value of a Mixed type has changed, call the .markModified(path) method of the document passing the path to the Mixed type you just changed.

Thus in embedded documents or arrays(which have no schema) which have mixed type(essentially no validation), you have to explicitly tell mongoose that the particular field has been modified before saving.

Have a look at the schema types and search for markModified. The API docs aren't informative.

As for your example,

 data2[0].markModified('videos')

will suffice. I assume data2[0] is a mongoDB document. You just need to give the path of the embedded document(mixed schema) inside which the changes take place. Not the innermost level which is changed.

For example if I have a schema - of model Artist, { name:String, albums: [{}] } If there is an document doc

{name:'artist1',
      albums:[
        {name:'album1',
         songs:[{name:'song1'},
                {name:'song2'},
                {name:'song3'}
               ]
        },
        {name:'album2',
         songs:[{name:'song4'},
                {name:'song5'},
                {name:'song6'}
               ]
       }
           ]
}

When I do a modification

doc.albums[1].songs[2]='song25'

I just need to specify the outermost path of the mixed type.

doc.markModified('albums')
doc.save();

Even if the albums array had another level of nesting, the markModified call will remain the same

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top