3

MongoDB 3.6 allow to perform complex array manipulations against all matching elements in any array – no matter how deeply nested – Update Nested Arrays with $[identifier]

Consider the document below on survey collection:

{
    "_id": "5a7d86d8fac139e71b0b9f5b",
    "results": [
      {
        "items": [
          {
            "comments": [
              {
                "id" : "123456",
                "email": "[email protected]",
                "content": "comment 1",
                "createdAt": "2018-05-03"
                "replies": []
              }
            ]
          }
        ]
      }
    ]
  }

I'm trying to update the comment email, content and createdAt fields and without touching to the id and replies fields.

I'm using $set and the new $[<identifier>]

I tried the command below based on The update command :

db.runCommand({
  update: "survey",
  updates: [
    {
      q: {},
      u: {
        $set: {
          "results.$[].items.$[].comments.$[comment]": {
            "email": "[email protected]",
            "content": "comment 2",
            "createdAt": "2018-05-04"
          }
        }
      },
      arrayFilters: [
        {
          "comment.id": { 
            $eq: "123456"
          }
        }
      ]
    }
  ]
})

The command works but it removes the id and replies fields.

Any help ? Thanks.

1 Answer 1

4

$set with document {} overwrites the matching document. Use $set and list all the document fields using dot notation to perform field level updates. More here.

db.runCommand({
  update: "survey",
  updates: [
    {
      q: {},
      u: {
        $set: {
          "results.$[].items.$[].comments.$[comment].email": "[email protected]",
          "results.$[].items.$[].comments.$[comment].content": "comment 2",
          "results.$[].items.$[].comments.$[comment].createdAt": "2018-05-04"
        }
      },
      arrayFilters: [
        {
          "comment.id": { 
            $eq: "123456"
          }
        }
      ]
    }
  ]
})
Sign up to request clarification or add additional context in comments.

2 Comments

This is an alternative, but in case when we have a lot of fields to update, it will be difficult to list them all like this.
Its either replace or you list them all. You can read all the fields from database and do a merge on client side and send the whole doc.

Your Answer

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.