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.
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.