potato
potato

Reputation: 223

Mongoose update value in Array of Array in NodeJS

my Test Schema:

var TestSchema = new Schema({
    testName: String,
    topic: {
        topicTitle: String,
        topicQuestion: [
            {
                questionTitle: String,
                choice: [
                    {
                        name: String
                        age: Number
                    }
                ]
            }
        ]
    }
}, { collection: 'test' });
var Test = mongoose.model('test', TestSchema);

I want to update one age ($inc)value which I have the choice id.

I can have test id, topicQuestion id and choice id.

How to write this query in mongoose in NodeJS?

Normally I use the below query to update a value:

Test.findOneAndUpdate({ _id: testId }, { $inc: { ... } }, function (err, response) {
   ...
});

but it is so difficult to get in array and one more array. Thanks

Upvotes: 0

Views: 45

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

You can use the $[] positional operator to update nested arrays.

router.put("/tests/:testId/:topicQuestionId/:choiceId", async (req, res) => {
  const { testId, topicQuestionId, choiceId } = req.params;

  const result = await Test.findByIdAndUpdate(
    testId,
    {
      $inc: {
        "topic.topicQuestion.$[i].choice.$[j].age": 1
      }
    },
    {
      arrayFilters: [{ "i._id": topicQuestionId }, { "j._id": choiceId }],
      new: true
    }
  );
  res.send(result);
});

Let's say we have this existing document:

{
    "_id" : ObjectId("5e53e7d9bf65ac4f5cbf2116"),
    "testName" : "Test 1",
    "topic" : {
        "topicTitle" : "Title",
        "topicQuestion" : [
            {
                "_id" : ObjectId("5e53e7d9bf65ac4f5cbf211a"),
                "questionTitle" : "Question 1 Title",
                "choice" : [
                    {
                        "_id" : ObjectId("5e53e7d9bf65ac4f5cbf211c"),
                        "name" : "A",
                        "age" : 1
                    },
                    {
                        "_id" : ObjectId("5e53e7d9bf65ac4f5cbf211b"),
                        "name" : "B",
                        "age" : 2
                    }
                ]
            },
            {
                "_id" : ObjectId("5e53e7d9bf65ac4f5cbf2117"),
                "questionTitle" : "Question 2 Title",
                "choice" : [
                    {
                        "_id" : ObjectId("5e53e7d9bf65ac4f5cbf2119"),
                        "name" : "C",
                        "age" : 3
                    },
                    {
                        "_id" : ObjectId("5e53e7d9bf65ac4f5cbf2118"),
                        "name" : "D",
                        "age" : 4
                    }
                ]
            }
        ]
    },
    "__v" : 0
}

If we want to increment age value of a given choice, we send a PUT request using endpoint like this http://.../tests/5e53e7d9bf65ac4f5cbf2116/5e53e7d9bf65ac4f5cbf211a/5e53e7d9bf65ac4f5cbf211b where

"testId": "5e53e7d9bf65ac4f5cbf2116"

"topicQuestionId": "5e53e7d9bf65ac4f5cbf211a"

"choiceId": "5e53e7d9bf65ac4f5cbf211b"

Upvotes: 1

rpereira15
rpereira15

Reputation: 197

You need to inform what choice you want and, on the update section, you need change the way you do increment.

Example:

Test.findOneAndUpdate({ _id: testId, topicQuestion.choice._id: choiceId}, { 'topicQuestion.$.choice': {$inc: { age: <numberToIncrement> }}}, {new: true}, function (err, response) {
   ...
});

Upvotes: 0

Related Questions