Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

like image 720
codeofnode Avatar asked May 23 '14 15:05

codeofnode


People also ask

How do I update nested objects?

To update nested properties in a state object in React: Pass a function to setState to get access to the current state object. Use the spread syntax (...) to create a shallow copy of the object and the nested properties. Override the properties you need to update.

How do I update a nested array in MongoDB?

Update Nested Arrays in Conjunction with $[] The $[<identifier>] filtered positional operator, in conjunction with the $[] all positional operator, can be used to update nested arrays. The following updates the values that are greater than or equal to 8 in the nested grades. questions array if the associated grades.

What is update return mongoose?

By default, findOneAndUpdate() returns the document as it was before update was applied. You should set the new option to true to return the document after update was applied. Mongoose's findOneAndUpdate() is slightly different from the MongoDB Node.

How do you use findByIdAndUpdate mongoose?

Mongoose | findByIdAndUpdate() Function The findByIdAndUpdate() function is used to find a matching document, updates it according to the update arg, passing any options, and returns the found document (if any) to the callback. Installation of mongoose module: You can visit the link to Install mongoose module.


2 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);
});
like image 60
Gergo Erdosi Avatar answered Nov 04 '22 20:11

Gergo Erdosi


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"
        }
    }
}))
like image 20
Rana Sarmad Rajput Avatar answered Nov 04 '22 22:11

Rana Sarmad Rajput