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
WHEREclause 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
iflag 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
1to include it. - Exclusion – set a field to
0to 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;
1for ascending,-1for 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:
- Are older than 28,
- Live in either Shanghai or Shenzhen,
- Have both “Node.js” and “Docker” listed in their
skillsarray, - Should not expose their
salaryfield, and - Need to be sorted by
experienceYearsdescending.
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!