Home > database >  Update different fields of multiple object based on IDs in array in mongoDb
Update different fields of multiple object based on IDs in array in mongoDb

Time:03-08

For instance, there is a following document in collection:

{
  _id: 'doc1',
  teams: [{
    _id: '1',
    name: 'team 1',
    color: 'red',
  }, {
    _id: '2',
    name: 'team 2',
    color: 'green',
  }, {
    _id: '3',
    name: 'team 3',
    color: 'blue',
  },
...]
}

And there is a partial update for teams:

{
  teams: [{
    _id: '1',
    name: 'A - team',
  }, {
    _id: '3',
    color: 'green',
  }]
}

To update the single element in array I can use $ operator like so:

db.collection.findOneAndUpdate({_id: 'doc1', 'teams._id':'1'}, {$set: {'teams.$.name': 'A - team'}})

However, I need to update multiple elements and get the result, what would be the best way to do it? Is there something similar to $push and $pull operators which works within a single operation?

CodePudding user response:

You may use arrayFilters , if you want to update different elements in array in single query based on array subdocument _id as follow:

db.collection.update({
 _id: "doc1"
},
{
 $set: {
         "teams.$[x].name": "A - team","teams.$[x].color": "green",
         "teams.$[y].name": "B - team","teams.$[y].color": "yellow",
         "teams.$[z].name": "C - team","teams.$[z].color": "pink"
   }
 },
{
 arrayFilters: [
  {
    "x._id": "1"
  },
  {
    "y._id": "2"
  },
  {
    "z._id": "3"
  }
 ]
})

Explained:

Create arrayFilters per array _id , and add $set statement in the update part of the update query for every defined filter in the example x,y,z.

playground

If you have those same array _id in multiple documents just remove the initial query part so the request to search on all collection , executing the update query with option {multi:true} will update all the documents where those _id's match not only the first match.

  • Related