Edit array element by index - Aggregation pipeline

How can we edit an array element by index in the aggregation pipeline?

1 Like

Hi,

There is a “hack” that you can use with $map and $range. For example, let’s say this is input document:

{
    "key": 1,
    "array": [
      1,
      2,
      3,
      4,
      5
    ]
  }

Now, let’s say you want to change 3rd element in array property to 100. You can do it like this:

  • $map with $range - to iterate over indexes from 0 to length of array property, and map its elements
  • $cond with $eq and $arrayElemAt - to check if index is equal to the index of element that you want to change. If it is, then change it. If it is not, do nothing.
db.collection.aggregate([
  {
    "$set": {
      "array": {
        "$map": {
          "input": {
            "$range": [
              0,
              {
                "$size": "$array"
              }
            ]
          },
          "in": {
            "$cond": [
              {
                "$eq": [
                  "$$this",
                  2
                ]
              },
              100,
              {
                "$arrayElemAt": [
                  "$array",
                  "$$this"
                ]
              }
            ]
          }
        }
      }
    }
  }
])

Note: Indexes of array start with 0, so to change 3rd element, we specified index of 2.

Working example

You may use dot notation to update directly by index.

mongosh> c.find()
[
  {
    _id: ObjectId("624da543790b00eaacae929e"),
    key: 1,
    array: [ 1, 2, 3, 4, 5 ]
  }
]

// change 3rd element to the value 369

mongosh> c.updateOne( { key : 1 } , { $set : { "array.2" : 369 } } )
{
  acknowledged: true,
  insertedId: null,
  matchedCount: 1,
  modifiedCount: 1,
  upsertedCount: 0
}

mongosh> c.find()
[
  {
    _id: ObjectId("624da543790b00eaacae929e"),
    key: 1,
    array: [ 1, 2, 369, 4, 5 ]
  }
]

Hi @steevej,

I don’t think that would work in Aggregation Pipeline. :smiley:

1 Like

Oops the missing part of my puzzle

I read Edit array element by index and jumped to the conclusion that he wanted to update the document in the database.

Note to self: must read better and completely. B-)

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.