Updating nested object in mongoose

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

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 : {} }

3 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); }); 
4

Hope I ain't late and will be able to help someone. This Works with deep nested objects as well. No limitations.

 const updateNestedObjectParser = (nestedUpdateObject) => { const final = { } Object.keys(nestedUpdateObject).forEach(k => { if (typeof nestedUpdateObject[k] === 'object' && !Array.isArray(nestedUpdateObject[k])) { const res = updateNestedObjectParser(nestedUpdateObject[k]) Object.keys(res).forEach(a => { final[`${k}.${a}`] = res[a] }) } else final[k] = nestedUpdateObject[k] }) return final } console.log(updateNestedObjectParser({ a: { b: { c: 99 }, d: { i: { l: 22 } } }, o: { a: 22, l: { i: "ad" } } })) 

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'); } }); 

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

You Might Also Like