MongoDB Read Operations
Introduction
Read operations in MongoDB allow you to retrieve data from your database collections. Whether you need to fetch a single document, multiple documents matching specific criteria, or analyze data with complex queries, MongoDB provides powerful tools to access your information efficiently.
In this tutorial, you'll learn how to:
- Query documents using the
find()
method - Structure queries with various operators
- Use projections to retrieve only needed fields
- Work with cursors for large result sets
- Perform advanced queries for real-world scenarios
Basic Read Operations
The find()
Method
The most fundamental way to query data in MongoDB is using the find()
method. This method returns a cursor to the matching documents.
Syntax
db.collection.find(query, projection)
Where:
query
(optional): Specifies selection criteria using query operatorsprojection
(optional): Specifies which fields to return in the matching documents
Finding All Documents
To retrieve all documents in a collection:
db.products.find()
This returns all documents in the "products" collection.
Finding Specific Documents
To find documents that match specific criteria:
db.products.find({ category: "Electronics" })
This returns all documents where the category field equals "Electronics".
Example Output
If you run the above query, the output might look like:
[
{
"_id": ObjectId("60a8f6d86b12b331acf25432"),
"name": "Smartphone",
"category": "Electronics",
"price": 699.99,
"stock": 50
},
{
"_id": ObjectId("60a8f6d86b12b331acf25433"),
"name": "Laptop",
"category": "Electronics",
"price": 1299.99,
"stock": 25
}
]
The findOne()
Method
If you need only the first matching document, use findOne()
:
db.products.findOne({ category: "Electronics" })
This returns only the first document that matches the criteria:
{
"_id": ObjectId("60a8f6d86b12b331acf25432"),
"name": "Smartphone",
"category": "Electronics",
"price": 699.99,
"stock": 50
}
Query Operators
MongoDB provides query operators that allow you to specify conditions for your queries.
Comparison Operators
Operator | Description |
---|---|
$eq | Equal to |
$gt | Greater than |
$gte | Greater than or equal to |
$lt | Less than |
$lte | Less than or equal to |
$ne | Not equal to |
$in | Matches any value in an array |
$nin | Does not match any value in an array |
Examples
Finding products with price greater than $1000:
db.products.find({ price: { $gt: 1000 } })
Finding products with prices between 1500:
db.products.find({ price: { $gte: 500, $lte: 1500 } })
Finding products that are either smartphones or laptops:
db.products.find({ name: { $in: ["Smartphone", "Laptop"] } })
Logical Operators
Operator | Description |
---|---|
$and | Logical AND |
$or | Logical OR |
$not | Logical NOT |
$nor | Logical NOR (neither condition is true) |
Examples
Finding products in Electronics category with price less than $800:
db.products.find({
$and: [
{ category: "Electronics" },
{ price: { $lt: 800 } }
]
})
A shorthand for the AND condition:
db.products.find({ category: "Electronics", price: { $lt: 800 } })
Finding products that are either in Electronics category or have a price less than $100:
db.products.find({
$or: [
{ category: "Electronics" },
{ price: { $lt: 100 } }
]
})
Projections
Projections allow you to control which fields are returned in the query results. This helps reduce network overhead and processing time.
Syntax
db.collection.find(query, { field1: 1, field2: 1 }) // Include only these fields
db.collection.find(query, { field1: 0, field2: 0 }) // Exclude these fields
Note: You cannot mix inclusion and exclusion in the same projection object, except for the _id
field.
Examples
Return only the name and price fields:
db.products.find({ category: "Electronics" }, { name: 1, price: 1 })
Output:
[
{
"_id": ObjectId("60a8f6d86b12b331acf25432"),
"name": "Smartphone",
"price": 699.99
},
{
"_id": ObjectId("60a8f6d86b12b331acf25433"),
"name": "Laptop",
"price": 1299.99
}
]
Return all fields except stock:
db.products.find({ category: "Electronics" }, { stock: 0 })
Exclude _id field and only include name and price:
db.products.find({ category: "Electronics" }, { _id: 0, name: 1, price: 1 })
Output:
[
{
"name": "Smartphone",
"price": 699.99
},
{
"name": "Laptop",
"price": 1299.99
}
]
Working with Cursors
When MongoDB returns query results, it does so using a cursor. A cursor is a pointer to the result set that allows you to iterate through the documents.
Cursor Methods
Here are some common cursor methods:
Method | Description |
---|---|
limit(n) | Limits the number of documents returned |
skip(n) | Skips the first n documents |
sort(criteria) | Sorts the results based on the criteria |
count() | Returns the count of matching documents |
toArray() | Converts the cursor to an array |
Examples
Limit the results to 5 documents:
db.products.find().limit(5)
Skip the first 10 documents (useful for pagination):
db.products.find().skip(10).limit(10) // Returns documents 11-20
Sort products by price in descending order:
db.products.find().sort({ price: -1 }) // -1 for descending, 1 for ascending
Sort by category ascending, then by price descending:
db.products.find().sort({ category: 1, price: -1 })
Count the number of electronics products:
db.products.find({ category: "Electronics" }).count()
Advanced Query Techniques
Query on Embedded Documents
To query an embedded document, use dot notation:
db.products.find({ "specs.ram": "8GB" })
Query Arrays
Find products with specific tag:
db.products.find({ tags: "bestseller" })
Find products with both tags:
db.products.find({ tags: { $all: ["bestseller", "sale"] } })
Find products by array element position:
db.products.find({ "tags.0": "bestseller" }) // "bestseller" is the first tag
Text Search
First, create a text index:
db.products.createIndex({ description: "text" })
Then, perform a text search:
db.products.find({ $text: { $search: "wireless headphones" } })
Real-World Examples
E-commerce Product Filtering
// Find available electronics between $500-$1000, sorted by price
db.products.find({
category: "Electronics",
price: { $gte: 500, $lte: 1000 },
inStock: true
}).sort({ price: 1 })
Pagination for Product Listing
// Page size: 10, Page number: 3
const pageSize = 10;
const pageNumber = 3;
const skip = pageSize * (pageNumber - 1);
db.products.find({
category: "Clothing"
})
.skip(skip)
.limit(pageSize)
.sort({ createdAt: -1 })
Dashboard Analytics Query
// Find top 5 products by sales in the last month
const oneMonthAgo = new Date();
oneMonthAgo.setMonth(oneMonthAgo.getMonth() - 1);
db.orders.aggregate([
{ $match: { orderDate: { $gte: oneMonthAgo } } },
{ $unwind: "$products" },
{ $group: {
_id: "$products.productId",
totalSold: { $sum: "$products.quantity" }
}},
{ $sort: { totalSold: -1 } },
{ $limit: 5 }
])
User Profile Data Retrieval
// Get user profile with selected fields
db.users.findOne(
{ username: "johndoe" },
{ _id: 0, password: 0, securityQuestions: 0 } // Exclude sensitive data
)
Query Performance Tips
-
Use indexes for frequently queried fields:
javascriptdb.products.createIndex({ category: 1, price: 1 })
-
Limit the fields returned with projections:
javascriptdb.products.find({}, { name: 1, price: 1, category: 1 })
-
Use
explain()
to analyze query performance:javascriptdb.products.find({ category: "Electronics" }).explain("executionStats")
-
Avoid querying for
null
values when possible:javascript// Instead of
db.products.find({ description: null })
// Use
db.products.find({ description: { $exists: false } })
Summary
MongoDB read operations offer powerful and flexible ways to query your data:
- Use
find()
andfindOne()
for basic queries - Apply query operators to filter data based on specific conditions
- Use projections to retrieve only needed fields
- Work with cursors for pagination and sorting
- Implement advanced queries for complex scenarios
By mastering read operations, you can efficiently retrieve the exact data you need from your MongoDB collections, improving your application's performance and user experience.
Additional Resources and Exercises
Practice Exercises
-
Basic Query Practice: Create a collection of books and write queries to find:
- All books by a specific author
- Books published after 2010
- Books with ratings above 4.5
-
Advanced Query Challenge: Create a collection of student records and write queries to find:
- Students who scored above 90 in math but below 80 in science
- Top 3 students by average score across all subjects
- Students who participate in both sports and music clubs
Further Learning
If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)