Home » Nodejs » Updating nested object in mongoose

Updating nested object in mongoose

Posted by: admin November 30, 2017 Leave a comment

Questions:

I have searched many questions on nested objects, but all I found where related to array[s].

I am looking for a updating simple nested object in mongoose.

From here http://mongoosejs.com/docs/guide.html

there is an example schema :
var blogSchema = new Schema({
  title:  String,
  author: String,
  body:   String,
  comments: [{ body: String, date: Date }],
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs:  Number
  }
});

Once created a document,

How can I change the favs number later on?

There is no document for the same that I could find.

This is what I did:

blog.findById(entityId, function(err, mainDoc){
      if(err || !mainDoc) return next(err || 'Document not found');
      var subDoc = mainDoc['meta'];
      if(subDoc){
        subDoc = _.extend(subDoc, { favs : 56 }); //_ lib already available
        console.log(mainDoc.get('meta')); //Prints the updated result with favs = 56  OK
        mainDoc.save(function(err, doc){
           console.log(doc.get('meta')); // prints the updated results with favs = 56 OK
        });
      } else next('Not found');
    });

Everything works file and all console gives the desired result.

But when I switch to mongoose console and query the document, I do not get the updated result.

I know there can be other ways to achieve the same, but I am only looking for what I am doing wrong in this particular code.

Why the console, after saving document, gives unmatched data from database?

Upon enabling the mongoose debug option, I found the in query there is no such data to be updated. Query fires with blank $set. { $set : {} }

Answers:

If you just want to change the value of favs, you can use a simpler query:

blog.findByIdAndUpdate(entityId, {$set: {'meta.favs': 56}}, function(err, doc) {
    console.log(doc);
});

Questions:
Answers:

The problem is that you can’t do anything with data from mongoose once you’ve got it other than sending it to the client.

HOWEVER, there is the lean method that makes it so you can then update the info and do whatever you want with it.

That would look like this:

blog.findById(entityId).lean().exec(function (err, mainDoc) {
    if (err || !mainDoc) {
        return next(err || 'Document not found');
    }
    var subDoc = mainDoc.meta;
    if(subDoc){
        subDoc.favs = 56;
        blog.update({_id: entityId}, mainDoc, function(err, doc){
            console.log(doc.get('meta'));
        });
    } else {
        next('Not found');
    }
});