Home > Blockchain >  How to edit multiple embedded documents in mongodb
How to edit multiple embedded documents in mongodb

Time:10-20

I want to find objects that match the following query and then set the events property to an empty array if it matches. Currently the query I'm using will only update the first embedded object in each document, but I need it to check every embedded object in each document. Here is the query, does anyone know how I can make this work?

const date_check = moment().subtract(10, 'minutes').format('X')

await Accumulator.updateMany(
    { 'data.lastUpdate': { $lt: date_check } },
    { 
        $set: {
            'data.$.events': []
        }
    }
)

The document looks like this...

{
    bookmaker: 'Bet365',
    sport: 'Football',
    data: [
        {
            lastUpdate: '2372273273',
            events: [
                ... // some event objects
            ]
        },
        {
            lastUpdate: '2372234421',
            events: [
                ... // some event objects
            ]
        },
        {
            lastUpdate: '2375343461',
            events: [
                ... // some event objects
            ]
        }
    ]
}

CodePudding user response:

I think its best to change your schema so lastUpdate to be a number for perfomance, and to avoid bugs, check $toInt, you can do it with code similar to the second query.

Query

  • arrayfilters way
  • replace "2372273273" with date_check
  • filter to keep the documents
  • use arrayFilters to make the change only the member-documents that pass the filter

Test code here

db.collection.update({
  "data.lastUpdate": {
    "$lt": "2372273273"
  }
},
{
  $set: {
    "data.$[data].events": []
  }
},
{
  "arrayFilters": [
    {
      "data.lastUpdate": {
        "$lt": "2372273273"
      }
    }
  ]
})

Query

  • alternative pipeline update way with $map
  • replace "2372273273" with date_check
  • filter to find the document
  • update only the members that the filter is true

pipeline update requires MongoDB >= 4.2

Test code here

db.collection.update({
  "data.lastUpdate": {
    "$lt": "2372273273"
  }
},
[
  {
    "$set": {
      "data": {
        "$map": {
          "input": "$data",
          "in": {
            "$cond": [
              {
                "$lt": [
                  "$$this.lastUpdate",
                  "2372273273"
                ]
              },
              {
                "$mergeObjects": [
                  "$$this",
                  {
                    "events": []
                  }
                ]
              },
              "$$this"
            ]
          }
        }
      }
    }
  }
])
  • Related