A Detailed Guide to Basic MongoDB Queries

MongoDB is a leading NoSQL document store that offers a highly flexible query language. Whether you are building a simple CRUD API or a complex analytics pipeline, mastering the basic query constructs is essential. This guide walks through the core syntax of the find() operation, common comparison and logical operators, pattern matching, array queries, field projection, result ordering, pagination, and simple counting. By the end, you should feel comfortable retrieving data from any collection using idiomatic MongoDB commands.

The find() Method

All read‑only queries start with the find() method on a collection object:

db.collection.find(filter, projection)
  • filter – a document that defines the selection criteria; it works like the WHERE clause in SQL.
  • projection – an optional document that specifies which fields to include or exclude in the returned documents.

A straightforward example that fetches every user whose age equals 25 looks like this:

db.users.find({ age: 25 })

If you also want to limit the output to just the name and email fields, you add a projection:

db.users.find({ age: 25 }, { name: 1, email: 1 })

Comparison Operators

MongoDB’s comparison operators are all prefixed with $. They let you express numeric, string, and date constraints with precision.

Operator Meaning
$eq equal to
$ne not equal to
$gt greater than
$gte greater than or equal to
$lt less than
$lte less than or equal to
$in value exists in a supplied array
$nin value does not exist in a supplied array

Example – age between 18 and 30 (inclusive of 30):

db.users.find({ age: { $gt: 18, $lte: 30 } })

Example – users living in one of several cities:

db.users.find({ city: { $in: ["Beijing", "Shanghai", "Guangzhou"] } })

Logical Operators

When a query involves multiple conditions, logical operators let you combine them in expressive ways.

  • $and – all listed expressions must be true (the default when you place several fields side‑by‑side).
  • $or – at least one expression must be true.
  • $not – negates a single expression.
  • $nor – none of the listed expressions may be true.

Example – users older than 25 or residing in Shenzhen:

db.users.find({
  $or: [
    { age: { $gt: 25 } },
    { city: "Shenzhen" }
  ]
})

Example – users who are not from New York and whose age is not 40:

db.users.find({
  $and: [
    { city: { $ne: "New York" } },
    { age: { $ne: 40 } }
  ]
})

Pattern Matching with Regular Expressions

MongoDB supports JavaScript regular expressions directly inside queries, providing functionality similar to SQL’s LIKE operator.

  • ^ anchors the pattern to the start of the string.
  • $ anchors the pattern to the end.
  • The i flag makes the match case‑insensitive.

Example – names that start with “Zhang”:

db.users.find({ name: /^Zhang/ })

Example – names that contain “ming” regardless of case:

db.users.find({ name: /ming/i })

Querying Array Fields

Arrays are first‑class citizens in MongoDB documents. The engine offers several operators to interrogate them.

  • Direct match – the query succeeds if the array contains the specified element.
  • $all – the array must contain all elements listed.
  • $size – matches arrays of an exact length.
  • $elemMatch – applies multiple criteria to the same array element.

Example – users who know Java:

db.users.find({ skills: "Java" })

Example – users who know both Java and Python:

db.users.find({ skills: { $all: ["Java", "Python"] } })

Example – users with exactly three listed skills:

db.users.find({ skills: { $size: 3 } })

Example – users whose skill entry includes a level of “expert” and a years‑of‑experience greater than 5:

db.users.find({
  skills: {
    $elemMatch: {
      level: "expert",
      years: { $gt: 5 }
    }
  }
})

Controlling the Result Set with Projection

By default, find() returns the entire document (including the automatically generated _id). Projection lets you trim the payload, which is especially useful for bandwidth‑sensitive applications.

  • Inclusion – set a field to 1 to include it.
  • Exclusion – set a field to 0 to omit it.

Important: You cannot mix inclusion and exclusion in the same projection, except for the _id field, which can be excluded independently.

Include only name and city (keep _id):

db.users.find({ age: { $gt: 18 } }, { name: 1, city: 1 })

Exclude the sensitive password field:

db.users.find({}, { password: 0 })

Sorting, Limiting, and Skipping

MongoDB returns a cursor that can be chained with additional methods to shape the final output.

  • sort() – orders the result set; 1 for ascending, -1 for descending.
  • limit() – caps the number of documents returned.
  • skip() – bypasses a specified number of documents, enabling pagination.

Example – top 10 oldest users:

db.users.find()
  .sort({ age: -1 })
  .limit(10)

Example – page 3 of a 10‑item‑per‑page view (i.e., items 21‑30):

db.users.find()
  .skip(20)   // (page‑1) * pageSize
  .limit(10)

Counting Matching Documents

When you need only the number of documents that satisfy a filter, countDocuments() is the most reliable choice because it respects the query’s semantics and any applied indexes.

db.users.countDocuments({ city: "Beijing" })

For quick existence checks, estimatedDocumentCount() can be used, but it ignores the filter and merely reports the collection’s total size.

Putting It All Together – A Sample Query

Suppose you want to retrieve the first five engineers who:

  1. Are older than 28,
  2. Live in either Shanghai or Shenzhen,
  3. Have both “Node.js” and “Docker” listed in their skills array,
  4. Should not expose their salary field, and
  5. Need to be sorted by experienceYears descending.

The complete query would look like this:

db.users.find(
  {
    age: { $gt: 28 },
    city: { $in: ["Shanghai", "Shenzhen"] },
    skills: { $all: ["Node.js", "Docker"] }
  },
  {
    salary: 0,          // exclude salary
    name: 1,
    city: 1,
    experienceYears: 1,
    skills: 1
  }
)
.sort({ experienceYears: -1 })
.limit(5)

Conclusion

Understanding the building blocks of MongoDB’s query language empowers you to write concise, performant data‑retrieval code. The find() method, together with comparison and logical operators, regular expressions, array‑specific queries, projection, and cursor modifiers (sort, skip, limit), covers the majority of everyday use cases. Once these fundamentals are solid, you’ll be ready to explore more advanced topics such as the Aggregation Pipeline, index design, and sharding strategies—each of which builds on the concepts introduced here. Happy querying!