I have this document structure:
{
"name": "ab",
"grades": [
{
"grade": "A",
"score": 1
},
{
"grade": "A",
"score": 12
},
{
"grade": "A",
"score": 7
}
],
"borough": "Manhattan2"
}
Assignment is to write a query to find the restaurants that have all grades with a score greater than 5.
The solution to the problem is following:
db.restaurants.find({
"grades": {
"$not": {
"$elemMatch": {
"score": {
"$lte": 5
}
}
}
}
})
I have troubles understanding proposed solution.
So far I have only used $elemMatch
to match at least one element of array or elements in array’s inner objects (grades.score
), but how the heck $not
is "somehow making" $elemMatch
to check for all grades.score
in this object?
I do understand general idea, "don’t look at score less the equal to 5, and what remains is what we need", but I cannot comprehend what does this code snippet returns:
"$not": {
"$elemMatch": {
"score": {
"$lte": 5
}
}
}
If was asked what does this query do before running & testing it, I would say that it find first score
that is greater then 5 and takes that document, but that is wrong, and I cannot figure why. I see that order of fields and keywords plays some role but don’t see the connection.
2
Answers
From the docs for
$elemMatch
{ "$elemMatch": { "score": { "$lte": 5 } } }
will match documents which have at least one array element withscore <= 5
.$not
on that will match documents which don’t meet that criteriascore <= 5
"score > 5
"In order to understand $elemMatch and $not, it would help if we start with $all.
As you we all know, $not is equal to say “No”, the opposite to “Yes”. We shall come to “No”
later. let us first start discussing $all, $elemMatch under the context of “Yes”.
Let us have a sample collection of just one document as below.
In Mongo shell:
First of $all :
Query 1 : found
Query 2: found
Query 3: Not found
What does it mean by $all ?
Th above three queries can be described in one line as “find all documents with the array key “a” has all elements in the given array”.
Now let us see $elemeMatch
Query 4 : found
Query 5 : found
Query 6 : Not found
What does it mean by $elemMatch ?
The above three queries can be described in one line as “find all documents with the array key “a” has at least one element matching the given condition”.
The take-away:
Please see the test results.
Notes:
$elemMatch can take more than one conditionals, for brevity, the examples in this post include just one condition. When there will be more than one condition, it would be evaluated with AND logical operation which is essentially the same as with just one condition.
Thanks
WeDoTheBest4You