Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
Query Operators  ›  Lesson

$in, $nin and $exists

$in 12 min$in matches a field equal to any value in a list, $nin matches when it equals none of them or is missing, and $exists tests whether a field is present at all.

$in, $nin and $exists

A customer ticks two genres on the filter panel: "myth" and "romance". Another wants anything except sci-fi. A data check needs every book that has never been rated. These are membership and presence questions, and three operators handle them.

The rule

$in: any of these. $nin: none of these. $exists: is it there at all?

_id title year price stock genres
1 Dune 1965 9.99 12 sci-fi, classic
2 Neuromancer 1984 8.5 0 sci-fi, cyberpunk
3 Emma 1815 4.25 7 classic, romance
4 The Hobbit 1937 7.99 3 fantasy, classic, adventure
5 Circe 2018 12 5 fantasy, myth

Dune, Neuromancer, Emma and The Hobbit have a ratings array (Emma's is empty, []); Circe has no ratings field. Only The Hobbit has signed: true.

db.books.find({ genres: { $in: ["myth", "romance"] } })      // Emma, Circe
db.books.find({ _id: { $in: [1, 3, 9] } })                   // Dune, Emma (no book 9)
db.books.find({ genres: { $nin: ["sci-fi", "fantasy"] } })   // Emma
db.books.find({ ratings: { $exists: false } })               // Circe
db.books.find({ signed: { $exists: true } })                 // The Hobbit
  • $in matches if the field equals any value in the list. On an array field, any element may match any listed value. It is a neater form of several equality tests on one field.
  • $nin matches if the field equals none of the values, including when the field is missing, just like $ne.
  • $exists: true matches documents that have the field, whatever its value, even null or []. $exists: false matches documents without it.

The shortcut

For $nin, cross out every document that contains a listed value; whatever survives matches, including documents missing the field.

`{ genres: { $nin: ["sci-fi", "fantasy"] } }`Step 1 of 4
  1. Cross out sci-fi

    Dune and Neuromancer contain "sci-fi". Out.

The trap is reading $exists: true as "has a useful value". Emma's empty ratings array exists, so it matches.

Drills

Answer fast — trust the rule.

quick drill

How many books match { genres: { $in: ["myth", "romance"] } }?

quick drill

How many books match { ratings: { $exists: true } }?

quick drill

Which filter returns books that are NOT by Frank Herbert or William Gibson?

quick drill

How many books match { signed: { $nin: [true] } }?

Remember

  • $in: any of these. $nin: none of these. $exists: is it there at all?
  • Shortcut: for $nin, cross out anything holding a listed value; the survivors match.
  • Trap: $nin matches missing fields, and $exists: true matches empty or null values.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainMembership and presence

Explain why { ratings: { $exists: false } } returns Circe but not Emma, then write filters for: books by either Jane Austen or Madeline Miller, and books with no sci-fi or fantasy genre. Give the results from the books collection.