Reputation: 1589
Given the following db
{
"type":"s",
"disp":[
{
"quantity":1,
"date":20141109
},
{
"quantity":1,
"date":20141110
},
{
"quantity":1,
"date":20141111
}
]
},
{
"type":"d",
"disp":[
{
"quantity":1,
"date":20141109
},
{
"quantity":0,
"date":20141110
},
{
"quantity":1,
"date":20141111
}
]
}
I perform a query to obtain a "type" with quantity grater then 0 for a set of dates
db.test.find({ "$and" : [
{ "disp" : { "$elemMatch" : { "quantity" : { "$gt" : 0 }, "date" : 20141109 } } },
{ "disp" : { "$elemMatch" : { "quantity" : { "$gt" : 0 }, "date" : 20141110 } } }
] },{"type":1})
I get the type "s" then I want to decrement by 1 only the quantity for the dates I just queried
I tried different kinds of update queries but I was able to change just one quantity field.
How can I do that in an atomic way ? If it's not possible can you advise me on a way to structure my data to query and atomically update quantity for specific dates ?
Upvotes: 1
Views: 239
Reputation: 19700
You can update only a single matching sub document in MongoDb, even if multiple sub documents match the query. Currently it is a limitation.
To update all the sub documents for each date, you need to fire n
update queries to update documents for n
different matching dates.
You need to make use of the $inc and the positional update $ operators.
var dates = [20141109,20141110];
dates.forEach(function(date){
db.test.update({"type":"s","disp.date":date},
{$inc:{"disp.$.quantity":1}})
})
Answering your questions:
atomically update quantity for specific dates
As per the documentation,
$inc is an atomic operation within a single document.
A suggestion:
n a way to structure my data to query
Never have two different sub documents for the same date as depicted in the example. If you would have then it makes no sense in updating two different sub documents for the same date.
{
"quantity":0,
"date":20141110
},
{
"quantity":1,
"date":20141110
}
Upvotes: 1