The Problem
Suppose I have a document as follows:
doc = {
"_id" : ObjectId("56464c726879571b1dcbac79"),
"food" : {
"fruit" : [
"apple",
"orange"
]
},
"items" : [
{
"item_id" : 750,
"locations" : [
{
"store#" : 13,
"num_employees" : 138
},
{
"store#" : 49,
"num_employees" : 343
}
]
},
{
"item_id" : 650,
"locations" : [
{
"store#" : 12,
"num_employees" : 22
},
{
"store#" : 15,
"num_employees" : 52
}
]
}
]
}
I would like to delete the element
{'#store#' : 12, 'num_employees' : 22}
but only if the following conditions are true:
food.fruitcontain the valuesappleororangeitem_idhas the id650
My Attempted Solution
I tried the following:
db.test.update({"food.fruit" : {"$in" : ["apple", "orange"]}, "items.item_id":650},{$pull:{'items.$.locations':{'store#':12,'num_employees':22}}})
The update does not work. Interestingly, if the $in operator part of the query is removed, it works. I'm using MongoDB v3.0.6 and consulted the MongoDB manual for the use of $(update):
https://docs.mongodb.org/manual/reference/operator/update/positional/
The docs contain a passage of interest:
Nested Arrays
The positional $ operator cannot be used for queries which traverse more than one array, such as queries that traverse arrays nested within other arrays, because the replacement for the $ placeholder is a single value
My query, of course, traverses more than one array. Indeed, if I remove 'food.fruit' : {$in : ['apple']} from the query, it works. However, this does
not solve my problem, because of course, I need that query. I'm looking for a solution that preferably:
- Does NOT require a schema change
- Executes in one query/update statement
$inhere as'food.fruit': 'apple'does the same thing, but the update works fine either way for me.apple. Example:{$in : ['apple', 'orange']}. Using your suggestion, I could do'food.fruit' : 'apple', 'food.fruit' : 'orange'which should be equivalent to using$in.food.fruithasappleororange. Just needs to have at least one of them.$in, as it should, because the limitation in the docs you reference is talking about trying to use$within a nested array (something besides the first level of the array).{'food.fruit' : 'apple', 'food.fruit' : 'orange'}is not equivalent to{'$in' : ['apple', 'orange']}