skip to Main Content

How can I push value into multiple nested array with specific conditions?
I have a document like this

[
  {
    "_id": "class_a",
    "students": [
      {
        "_id": "1a",
        "name": "John",
        "grades": []
      },
      {
        "_id": "1b",
        "name": "Katie",
        "grades": []
      },
      {
        "_id": "1c",
        "name": "Andy",
        "grades": []
      },
      
    ]
  }
]

Query to insert into nested array. (Not sure what is missing here)

db.collection.update({
  "_id": "class_a",
  "students": {
    $elemMatch: {
      "_id": {
        "$in": [
          "1a",
          "1b"
        ]
      }
    }
  }
},
{
  $push: {
    "students.$.grades": "A+"
  }
})

Got the following result. But I was expecting both John and Katie have A+ in grades

[
  {
    "_id": "class_a",
    "students": [
      {
        "_id": "1a",
        "grades": ["A+"],
        "name": "John"
      },
      {
        "_id": "1b",
        "grades": [],
        "name": "Katie"
      },
      {
        "_id": "1c",
        "grades": [],
        "name": "Andy"
      }
    ]
  }
]

Expected result

[
  {
    "_id": "class_a",
    "students": [
      {
        "_id": "1a",
        "grades": ["A+"],
        "name": "John"
      },
      {
        "_id": "1b",
        "grades": ["A+"],
        "name": "Katie"
      },
      {
        "_id": "1c",
        "grades": [],
        "name": "Andy"
      }
    ]
  }
]

Mongo playground to test the code

2

Answers


  1. You can use $[<identifier>] to update only the items that match a condition. Your first {} is to find the relevant documents, while the arrayFilters is to find the relevant items inside the document nested array:

    db.collection.update(
      {_id: "class_a", students: {$elemMatch: {_id: {$in: ["1a", "1b"]}}}},
      {$push: {"students.$[item].grades": "A+"}},
      {arrayFilters: [{"item._id": {$in: ["1a", "1b"]}}], upsert: true}
    )
    

    See how it works on the playground example

    Login or Signup to reply.
  2. You should really use arrayFilters for these otherwse it’ll only match the first entity. You don’t need to use $elemMatch at all.

    Playground – https://mongoplayground.net/p/_7y89KB83Ho

    db.collection.update({
      "_id": "class_a"
    },
    {
      $push: {
        "students.$[students].grades": "A+"
      }
    },
    {
      "arrayFilters": [
        {
          "students._id": {
            "$in": [
              "1a",
              "1b"
            ]
          }
        }
      ]
    })
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search