Reputation: 733
Lets say there is an object like this in the db:
{
_id: <...>,
arrayOfObjects: [
{
criteria: "one",
value: 5
},
{
criteria: "two",
value: 5
},
{
criteria: "three",
value: 5
},
{
criteria: "four",
value: 5
},
]
}
What I want to do is to run an update similar to:
{
$inc: {
"arrayOfObjects.2.value" : -1
}
}
However I need it to affect only certain elements, e.g. {$or: [{criteria: "one"}, {criteria: "three"}]} I cannot rely on array indexes as the object copy I have may have expired before the update is executed (objects can be inserted, deleted, rearranged in the array).
Is it possible to pull this off? What would be the optimal way to do this?
Upvotes: 1
Views: 107
Reputation: 222511
I do no know what why exactly you can not run Michai's query, because in my opinion it is correct. So I am posting my answer. First of all, you can not do this in one query. Yes, sounds ridiculous but here is the thing : https://jira.mongodb.org/browse/SERVER-1243
May this is a good idea to write or upvote this issue there and may be in next few months they will solve it. But judging by the creating time of the post 2010 I highly doubt that :-(
So here are some workarounds how you can do it: First of all if there are not a lot of criteria than you can do this using multiple queries:
db.coll.update({
_id: <...>,
'arrayOfObjects.criteria': 'Criteria 1'
}, {
'arrayOfObjects.$.value': {
$inc: -1
}
})
and doing this as many times as you have different criteria.
But if there are too many criteria it you can waste too many queries. So you will be able to do this in two queries in any case.
db.coll.find( {'arrayOfObjects.criteria' : { $in: ['one', 'three'] }})
Upvotes: 0
Reputation: 2760
Use this query
{$or: [{arrayOfObjects.criteria: "one"}, {arrayOfObjects.criteria: "three"}]}
For your update
EDIT:
Try this
collectionName.update({arrayOfObjects.criteria: "one"}, {$inc: {"arrayOfObjects.$.value" : -1}}, false, true);
collectionName.update({arrayOfObjects.criteria: "three"}, {$inc: {"arrayOfObjects.$.value" : -1}}, false, true);
Also, have a look at this link for more info on mongodb updates http://www.mongodb.org/display/DOCS/Updating#Updating-update%28%29
Edited my answer.
@JohnnyHK is right. It requires 2 queries. My bad. It's late and I'm tired :)
Upvotes: 0
Reputation: 311855
You would have to do this as two separate update
commands, because the $
positional operator only identifies the first array element matched:
db.coll.update({_id: <...>, 'arrayOfObjects.criteria': 'one'},
{'arrayOfObjects.$.value': {$inc: -1}})
db.coll.update({_id: <...>, 'arrayOfObjects.criteria': 'three'},
{'arrayOfObjects.$.value': {$inc: -1}})
Upvotes: 1