Home > other >  How can I increment something inside an array in MongoDB?
How can I increment something inside an array in MongoDB?

Time:10-28

I have a collection with documents structured like this

{
    _id: 140,
    first_list: [
        {
            _id: ObjectId('623db7e840651f2b7f107ee0'),
            second_list: [
                {
                    _id: ObjectId('6241808340651f2b7f108123'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
                {
                    _id: ObjectId('6241809640651f2b7f108125'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
                {
                    _id: ObjectId('624180ac40651f2b7f108127'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
            ]
        }
        {
            _id: ObjectId('623db7e840651f2b7f107ee2'),
            second_list: [
                {
                    _id: ObjectId('6241808340651f2b7f108155'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
                {
                    _id: ObjectId('6241809640651f2b7f108157'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
                {
                    _id: ObjectId('624180ac40651f2b7f108159'),
                    start_date: ISODate('2022-05-29T22:00:00.000Z'),
                    end_date: ISODate('2022-06-09T22:00:00.000Z'),
                },
           ]
    ]
}

and I would like to increment all the end_dates (of all the documents in the collection!) by one hour.

If end_date was just an item of the outer document, I would have done like this

db.collection.updateMany( {}, [{ $set: { end_date: { $add: ["$end_date", 1 * 60 * 60000] } } }])

but I'm having problems because of the array structure. I tried to read both here and here but couldn't solve my problem yet.

I hope you can help me. Thank you very much.

CodePudding user response:

Here's one way to do it by using a pipeline in the update.

db.collection.update({
  "first_list.second_list.end_date": {
    "$exists": true
  }
},
[
  {
    "$set": {
      "first_list": {
        // rewrite each element of first_list
        "$map": {
          "input": "$first_list",
          "as": "elem1",
          "in": {
            // keep everything from elem1 and rewrite second_list
            "$mergeObjects": [
              "$$elem1",
              {
                "second_list": {
                  // rewrite each element of second_list
                  "$map": {
                    "input": "$$elem1.second_list",
                    "as": "elem2",
                    "in": {
                      // keep all from elem2 and rewrite end_date
                      "$mergeObjects": [
                        "$$elem2",
                        {
                          "end_date": {
                            "$dateAdd": {
                              "startDate": "$$elem2.end_date",
                              "unit": "hour",
                              "amount": 1
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  }
],
{"multi": true}
)

Try it on mongoplayground.net.

  • Related