Chapter 1: Basic Aggregation - $match and $project

Hello !

A little reminder before asking my question :

  • imdb.rating is at least 7
    
  • genres does not contain "Crime" or "Horror"
    
  • rated is either "PG" or "G"
    
  • languages contains "English" and "Japanese"
    

From the MongoDB doc :
The $all is equivalent to an $and operation of the specified values.

But when I use $all I’m getting 24 documents and with $and 23 documents.

Why is that ?

Most likely there is a typo. Please provide the 2 clauses for which you have an issue. If the doc says they are equivalent then they should so if they are not in your case the problem lies somewhere else.

23 documents :

[ { $match:
...,
"$and": [{"genres": {"$ne": "Crime"}}, {"genres": {"$ne": "Horror"}}]
...,
}]

24 documents :

[ { $match:
...,
"genres": {"$ne": {"$all": ["Crime", "Horror"]}}
...,
}]

or even :

[ { $match:
...,
"genres": {"$not": {"$all": ["Crime", "Horror"]}}
...,
}]
1 Like

The $ne and and $not of the non-working one are the tricky parts.

The { genres : { “$all” : [ “Crime” , “Horror” ] } } gives 5 documents.
However “genres”: {"$not": {"$all": [“Crime”, “Horror”]}} gives 2245 documents. If you look at the documents returned you will see plenty of with genres:Crime or genres:Horror. Because these documents contains either Crime or Horror but not both.

I hope you can see that the working one and the non working ones are not logically equivalent.

3 Likes

This troubled, so I run some tests and what I got back is that $nor or $nin are more logically suitable for this scenario since we are dealing with arrays, they’ll both give you the expected result.

$nor": [{“genres”: “Crime”}, {“genres”: “Horror”}] or “genres”: { “$nin”: [ “Crime”, “Horror”]}

Hey @Henry, I found this helpful, https://www.bmc.com/blogs/mongodb-operators/

Hi, I have the same problem here.

I get 24 documents with
"$and": [ { "genres": { "$ne": "Crime" } }, { "genres": { "$ne": "Horror" } } ]
this operation includes one wrong document which have “Crime” genre,

and 23 documents with
"$nor": [ { "genres": "Crime" }, { "genres": "Horror" } ]

I don’t understand what is the difference.
Do I have to use array operator like $nin ?