1

I am having hard time figuring out how to increment a value in an object within an array

For instance I have this document based on Poll schema:

{
 "_id": "584b2cc6817758118e9557d8",
 "title": "Number of Skittles",
 "description": "Test1",
 "date": "Dec 9, 2016",
 "__v": 0,
 "labelOptions": [
 {
 "Bob": 112
 },
 {
 "Billy": 32
 },
 {
 "Joe": 45
 }
 ]
}

Using express, I am able to get this far:

app.put('/polls/:id', function(req, res){
 let id = req.params.id;
 let labelOption = req.query.labelOption;
 Poll.findOneAndUpdate(
 {'_id' : id},
 {$inc: {`labelOptions.$.${labelOption}`: 1 }},
 function(err){
 console.log(err)
 })

where labelOption is the one that I would like to increment its value

To be more concise, I am having trouble transversing inside the document.

asked Dec 10, 2016 at 5:36

3 Answers 3

6

There is another way to do this which allows a more flexible document model. If you add a field to your object like:

{
 "_id": "584b2cc6817758118e9557d8",
 "title": "Number of Skittles",
 "description": "Test1",
 "date": "Dec 9, 2016",
 "__v": 0,
 "labelOptions": [
 {
 "name": "Bob",
 "number": 112
 },
 {
 "name": "Billy",
 "number": 32
 },
 {
 "name": "Joe"
 "number": 45
 }
 ]
}

Then you can do:

app.put('/polls/:id', function(req, res){
 let id = req.params.id;
 let labelOption = req.query.labelOption;
 Poll.findOneAndUpdate(
 {
 '_id' : id,
 'labelOptions.name': labelOption
 },
 {$inc: {
 "labelOptions.$.number": 1 
 }},
 function(err){
 console.log(err)
 })
 });
answered May 7, 2019 at 9:16
Sign up to request clarification or add additional context in comments.

Comments

5

It is not possible to directly increment the value in the .find query if labelOptions is an Array of Object. To make it easier, you should change the labelOptions type from Array of Objects to Object:

"labelOptions": {
 "Bob": 112,
 "Billy": 32,
 "Joe": 45
};

Also consider using .findByIdAndUpdate instead of .findOneAndUpdate if you are querying by the document's _id. And then, you can achieve what you want by:

Poll.findByIdAndUpdate(
 id,
 {$inc: {`labelOptions.${labelOption}`: 1 }},
 function(err, document) {
 console.log(err);
});

UPDATE: If you are persistent on using Array of Objects for labelOptions, there is a workaround:

Poll.findById(
 id,
 function (err, _poll) {
 /** Temporarily store labelOptions in a new variable because we cannot directly modify the document */
 let _updatedLabelOptions = _poll.labelOptions;
 /** We need to iterate over the labelOptions array to check where Bob is */
 _updatedLabelOptions.forEach(function (_label) {
 /** Iterate over key,value of the current object */
 for (let _name in _label) {
 /** Make sure that the object really has a property _name */
 if (_label.hasOwnProperty(_name)) {
 /** If name matches the person we want to increment, update it's value */
 if (_name === labelOption) ++_label._name;
 }
 }
 });
 /** Update the documents labelOptions property with the temporary one we've created */
 _poll.update({labelOptions: _updatedLabelOptions}, function (err) {
 console.log(err);
 });
 });
answered Dec 10, 2016 at 7:34

Comments

0

People solved it but, if you use that for if element in array doesnt exits, a solution:

 app.put('/polls/:id', async function (req, res) {
 let id = req.params.id;
 let labelOption = req.query.labelOption;
 const exits = await Poll.exists({ _id: id, "labelOptions.name": labelOption });
 if (exits)
 await Poll.updateOne(
 { _id: id, "labelOptions.name": labelOption },
 {
 $inc: {
 "labelOptions.$.number": 1
 }
 }
 );
 else
 await Poll.updateOne({ _id: id }, {
 $push: {
 labelOptions: {
 name: labelOption,
 number: 1
 }
 }
 });
 });
answered Sep 10, 2023 at 8:51

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.