You can not do this at the moment with one query. One reasonable way to achieve this would have been to use $pull and $push like this:
db.a.update({
tags : 'foo'
},{
$pull : {tags : 'foo'},
$push : {tags : 'bar'}
},{
multi : true
})
But this would end up with Field name duplication not allowed with modifiers error message which is basically tells you that you can not use $pull and $push at the same time. Jira ticket was filed few years ago, but still it is unresolved (and based on Minor label here it is highly unlikely to be resolved soon).
One way to go with it is to run a query to find IDs of the documents that has foo
, then another query to remove all these foo
and another one to insert bars
for all IDs. I know that potentially in between of these updates something can modify the collection, but this is one option.
Another way is to iterate through all the elements which has tags as foo and to modify them in foreach statement.