Episode 6 of 17
Query Documents
Learn how to query and retrieve documents from MongoDB using find(), findOne(), comparison operators ($eq, $gt, $lt, $in), regex matching, and querying nested documents and arrays.
Querying is where MongoDB truly shines. The query language is expressive, supports complex filters, and feels natural for developers. This episode covers the fundamental query operations you'll use every day.
find() — Retrieve Multiple Documents
// Find ALL documents in a collection
db.users.find()
// Pretty-print the output
db.users.find().pretty()
// Find with a filter — exact match
db.users.find({ role: "developer" })
// Find with multiple conditions (implicit AND)
db.users.find({ role: "developer", age: 28 })
findOne() — Retrieve a Single Document
// Returns the first matching document
db.users.findOne({ email: "alice@example.com" })
// Find by _id
db.users.findOne({ _id: ObjectId("65a1b2c3d4e5f6a7b8c9d0e1") })
Comparison Operators
// $eq — Equal to (same as implicit match)
db.users.find({ age: { $eq: 28 } })
// $ne — Not equal to
db.users.find({ role: { $ne: "manager" } })
// $gt — Greater than
db.users.find({ age: { $gt: 30 } })
// $gte — Greater than or equal to
db.users.find({ age: { $gte: 30 } })
// $lt — Less than
db.users.find({ age: { $lt: 30 } })
// $lte — Less than or equal to
db.users.find({ age: { $lte: 30 } })
// $in — Matches any value in an array
db.users.find({ role: { $in: ["developer", "designer"] } })
// $nin — Does not match any value in an array
db.users.find({ role: { $nin: ["manager", "admin"] } })
Combining Multiple Operators
// Age between 25 and 35
db.users.find({
age: { $gte: 25, $lte: 35 }
})
// Role is developer AND age is greater than 25
db.users.find({
role: "developer",
age: { $gt: 25 }
})
Querying Nested Documents
Use dot notation to query fields inside nested objects:
// Query by nested field
db.orders.find({ "customer.city": "Mumbai" })
// Query deeply nested fields
db.orders.find({ "customer.address.state": "Karnataka" })
// Multiple nested conditions
db.orders.find({
"customer.address.city": "Bangalore",
status: "processing"
})
Important: Always use quotes around dot-notation field names.
Querying Arrays
// Find documents where the array contains a specific value
db.posts.find({ tags: "mongodb" })
// Find documents where the array contains ALL specified values
db.posts.find({ tags: { $all: ["mongodb", "nosql"] } })
// Find by array element at a specific index
db.posts.find({ "tags.0": "mongodb" })
// Find by array length
db.posts.find({ tags: { $size: 3 } })
$elemMatch — Query Array of Objects
// Find orders with an item that costs more than 50000
db.orders.find({
items: {
$elemMatch: {
price: { $gt: 50000 }
}
}
})
// Find orders with a specific product AND quantity > 1
db.orders.find({
items: {
$elemMatch: {
product: "Mouse",
qty: { $gt: 1 }
}
}
})
Regex Queries
// Find names starting with "A"
db.users.find({ name: /^A/ })
// Case-insensitive search
db.users.find({ name: /alice/i })
// Using $regex operator
db.users.find({
email: { $regex: "@example\.com$", $options: "i" }
})
// Find titles containing "MongoDB" (case-insensitive)
db.posts.find({
title: { $regex: "mongodb", $options: "i" }
})
$exists and $type
// Find documents that HAVE a specific field
db.users.find({ phone: { $exists: true } })
// Find documents that DON'T have a field
db.users.find({ phone: { $exists: false } })
// Find documents where a field is a specific type
db.users.find({ age: { $type: "number" } })
// Find documents where a field is null
db.users.find({ deletedAt: null })
// Find only documents where the field EXISTS and is null
db.users.find({ deletedAt: { $exists: true, $eq: null } })
Counting Documents
// Count all documents
db.users.countDocuments()
// Count with a filter
db.users.countDocuments({ role: "developer" })
// Estimated count (faster, uses metadata)
db.users.estimatedDocumentCount()
Distinct Values
// Get all unique roles
db.users.distinct("role")
// Output: ["developer", "designer", "manager"]
// Distinct with a filter
db.users.distinct("role", { age: { $gt: 30 } })
What's Next
You now know how to query documents with various filters and operators. In the next episode, we'll combine these with AND and OR logical operators to build complex, multi-condition queries.