0

Inspired by another question I was looking for a common way to add a field with the index to each item in a nested array.

Assuming my document looks like:

  {
    _id: ObjectId("5a934e000102030405000000"),
    events: [
      {
        status: 0,
        timestamp: ISODate("2022-05-29T13:26:00Z")
      },
      {
        status: 8,
        timestamp: ISODate("2022-05-29T14:41:00Z")
      },
      {
        status: 4,
        timestamp: ISODate("2022-05-31T10:13:00Z")
      },
      {
        status: 3,
        timestamp: ISODate("2022-05-31T10:18:00Z")
      }
    ]
  }

And I want each item to contain a new field which is the index of the item in the array:

{
    _id: ObjectId("5a934e000102030405000000"),
    events: [
      {
        arrayIndex: 0,
        status: 0,
        timestamp: ISODate("2022-05-29T13:26:00Z")
      },
      {
        arrayIndex: 1,
        status: 8,
        timestamp: ISODate("2022-05-29T14:41:00Z")
      },
      {
        arrayIndex: 2,
        status: 4,
        timestamp: ISODate("2022-05-31T10:13:00Z")
      },
      {
        arrayIndex: 3,
        status: 3,
        timestamp: ISODate("2022-05-31T10:18:00Z")
      }
    ]
  }

1 Answer 1

0

Since mongoDB version 3.4, this can be done using an aggregation pipeline with a $reduce phase, which uses the size of the new accumulated array:

db.collection.aggregate([
  {$project: {
      events: {
        $reduce: {
          input: "$events",
          initialValue: [],
          in: {
            $concatArrays: [
              "$$value",
              [
                {$mergeObjects: [
                    "$$this",
                    {arrayIndex: {$size: "$$value"}}
                ]}
              ]
            ]
          }
        }
      }
  }}
])

See how it works on the playground example

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

Comments

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.