The positional operator can be used only once in a query. This is a limitation, there is an open ticket for improvement: https://jira.mongodb.org/browse/SERVER-831
An other way to solve this problem could be to push "item5" to the array and pull "item4". Something like this:
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" }, $push: { "resources.$.resource_list": "item5" } })
However this isn't possible either, $pull
and $push
can't be used in the same query for the same field. Related ticket: https://jira.mongodb.org/browse/SERVER-1050
I see two solutions. One is to execute two queries. In the first query, you push "item5", in the second query you pull "item4":
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $push: { "resources.$.resource_list": "item5" } });
db.resource.update({ "resources.resource_id": 2, "resources.resource_list": "item4" }, { $pull: { "resources.$.resource_list": "item4" } });
If you want to do it in one query, you can use mongo shell. Something like this:
db.resource.find({ 'resources.resource_id': 2, 'resources.resource_list': 'item4' }).forEach( function(document) {
for (var i in document.resources) {
if (document.resources[i].resource_id == 2) {
var index = document.resources[i].resource_list.indexOf('item4');
document.resources[i].resource_list[index] = 'item5';
db.resource.save(document);
}
}
})