0

I have the object below. "questions" is the document name and each question has a nested array of type answers property where some answers has a propoerty call status.

questions = [
{
    "_id": "idq1"
    "author" :"auth1"
    "Answers": []
},
{
    "_id": "idq2"
    "author" :"auth2"
    "Answers": [
        {
            "author": "auth1",
            "comments" [...],
            "status" : "1"
        },
        {
            "author": "auth2",
            "comments" [...],
        },
        {
            "author": "auth3",
            "comments" [...],
            "status" : "0"
        }
    ]
}
]

I need to update all the nested Answers.status = "1" , where the Answers length > 0 and the nested element "status" does not exist. so the result would be :

questions = [
{
    "_id": "idq1"
    "author" :"auth1"
    "Answers": []
},
{
    "_id": "idq2"
    "author" :"auth2"
    "Answers": [
        {
            "author": "auth1",
            "comments" [...],
            "status" : "1"
        },
        {
            "author": "auth2",
            "comments" [...],
                "status" : "1"
        },
        {
            "author": "auth3",
            "comments" [...],
            "status" : "0"
        }
    ]
}
]
2
  • Is "questions" also a field? Can you add the proper sample document? Commented May 26, 2020 at 4:27
  • 1
    questions is the document name and each question has a nested answers property where each answers has a status. Commented May 26, 2020 at 4:32

2 Answers 2

2

You can use the arrayFilters for updating the array fields

Here I'm adding the query to update the document as required:

I have used the multi: true along with the arrayFilter to update multiple documents.

db.questions.update(
  {
    "Answers":{
      $nin:[
        [],
        null
      ]
    }
  },
  {
    $set:{
      "Answers.$[ans].status":"1"
    }
  },
  {
    arrayFilters:[
      {
        "ans.status":{
          $exists:false
        }
      }
    ],
    multi:true
  }
)

Sample output

{
    "_id": "idq1"
    "author" :"auth1"
    "Answers": []
},
{
    "_id": "idq2"
    "author" :"auth2"
    "Answers": [
        {
            "author": "auth1",
            "comments": [...],
            "status" : "1"
        },
        {
            "author": "auth2",
            "comments": [...],
            "status" : "1"
        },
        {
            "author": "auth3",
            "comments": [...],
            "status" : "0"
        }
    ]
}

For more about arrayFilters refer here.

Hope this will help :)

Sign up to request clarification or add additional context in comments.

2 Comments

Instead of $nin. best to use { "Answers.1" : {$exists : true} }
thanks @nayakam, that was helpful. Added to my knowledge :)
1

My latest working code :

questions.updateMany(
            {
                "Answers.status" :null
            },
            { $set: { "Answers.$[i].status": 1 } },
            { new: true,
                arrayFilters: [{ "i.status": null}]        
            });

1 Comment

But this will not be able to update the "status" field if the "status" is not present in two or more documents of the same "Answers" array. If that's not the use case then it's okay :)

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.