MongoDB Explained — NoSQL Database for Beginners
MongoDB is a NoSQL document database that stores data in flexible, JSON-like documents, enabling developers to work with data in a natural, schema-less way that maps directly to objects in modern programming languages.
What You’ll Learn
By the end of this tutorial, you’ll understand document databases, perform CRUD operations in MongoDB, use the aggregation pipeline, and know when MongoDB is the right choice compared to SQL databases like MySQL and PostgreSQL.
Why MongoDB Matters
MongoDB is the most popular NoSQL database, used by companies like Uber, eBay, and Google. It excels at handling large volumes of unstructured or semi-structured data, rapid prototyping, and applications requiring flexible schemas.
MongoDB Learning Path
flowchart LR
A[SQL Basics] --> B[MySQL]
B --> C[PostgreSQL]
C --> D[MongoDB]
D --> E[Redis]
E --> F[Database Design]
D --> G{You Are Here}
style G fill:#f90,color:#fff
What Is MongoDB? (The “Why” First)
Think of MongoDB like a digital filing cabinet where each file can be completely different. In a relational database, every file must follow the same rigid template. In MongoDB, one file might have 5 fields, another might have 10, and a third might have nested sections — all stored together.
Document vs Relational — A Visual Difference
Relational (MySQL):
Table: users
| id | first_name | last_name | email | phone |
|----|------------|-----------|-----------------|------------|
| 1 | Alice | Johnson | alice@email.com | 555-0101 |Document (MongoDB):
{
"_id": ObjectId("..."),
"name": { "first": "Alice", "last": "Johnson" },
"email": "alice@email.com",
"phone": "555-0101",
"address": {
"street": "123 Main St",
"city": "New York",
"zip": "10001"
},
"tags": ["premium", "newsletter"]
}Key Concepts
Documents
A document is a record in MongoDB, stored as JSON-like BSON (Binary JSON). It’s equivalent to a row in a relational table but flexible — no two documents need the same fields.
Collections
A collection is a group of documents, equivalent to a table in relational databases. But unlike a table, a collection doesn’t enforce a schema.
The _id Field
Every document must have an _id field (primary key). If you don’t provide one, MongoDB generates an ObjectId automatically:
ObjectId("507f1f77bcf86cd799439011")
// Contains: timestamp (4 bytes) + machine ID (3) + process ID (2) + counter (3)
CRUD Operations in MongoDB
Let’s work with a products collection for an e-commerce store:
Inserting Documents
// Insert one document
db.products.insertOne({
name: "Wireless Mouse",
price: 29.99,
category: "electronics",
stock: 150,
tags: ["wireless", "mouse", "computer"],
ratings: { average: 4.5, count: 230 }
});
// Insert multiple documents
db.products.insertMany([
{
name: "USB-C Hub",
price: 49.99,
category: "electronics",
stock: 80,
tags: ["usb", "hub", "accessories"],
ratings: { average: 4.2, count: 145 }
},
{
name: "Notebook Set",
price: 14.99,
category: "stationery",
stock: 500,
tags: ["notebook", "paper"],
ratings: { average: 4.8, count: 89 }
},
{
name: "Desk Lamp",
price: 39.99,
category: "furniture",
stock: 45,
tags: ["lamp", "led", "desk"],
ratings: { average: 4.0, count: 67 }
}
]);Output:
{ acknowledged: true, insertedIds: { '0': ObjectId("..."), '1': ObjectId("..."), '2': ObjectId("...") } }Querying Documents (SELECT equivalent)
// Find all products
db.products.find();
// Find with filtering (WHERE equivalent)
db.products.find({ category: "electronics" });
// Find with comparison operators
db.products.find({ price: { $lt: 30 } }); // price < 30
db.products.find({ price: { $gte: 20, $lte: 50 } }); // price between 20 and 50
db.products.find({ stock: { $gt: 100 } }); // stock > 100
// Find with multiple conditions
db.products.find({
category: "electronics",
price: { $lt: 50 },
"ratings.average": { $gte: 4.0 }
});
// Projection (SELECT specific columns)
db.products.find(
{ category: "electronics" },
{ name: 1, price: 1, _id: 0 } // 1 = include, 0 = exclude
);Output (last query):
[
{ name: "Wireless Mouse", price: 29.99 },
{ name: "USB-C Hub", price: 49.99 }
]Updating Documents
// Update one document
db.products.updateOne(
{ name: "Wireless Mouse" }, // filter
{ $set: { price: 27.99 }, // set new values
$inc: { stock: -1 } } // increment/decrement
);
// Update multiple documents (increase all electronics prices by 10%)
db.products.updateMany(
{ category: "electronics" },
{ $mul: { price: 1.10 } }
);
// Replace an entire document
db.products.replaceOne(
{ name: "Desk Lamp" },
{
name: "LED Desk Lamp",
price: 44.99,
category: "furniture",
stock: 60,
tags: ["lamp", "led", "desk", "energy-saving"],
ratings: { average: 4.1, count: 72 }
}
);Deleting Documents
// Delete one
db.products.deleteOne({ name: "USB-C Hub" });
// Delete many (delete all products with 0 stock)
db.products.deleteMany({ stock: 0 });
// Delete all documents (but keep the collection)
db.products.deleteMany({});
// Drop the entire collection
db.products.drop();Aggregation Pipeline — MongoDB’s GROUP BY
The aggregation pipeline is MongoDB’s equivalent of GROUP BY, joins, and complex transformations. It processes documents through a series of stages:
// Aggregation pipeline: find top categories by average rating
db.products.aggregate([
// Stage 1: Filter (like WHERE)
{ $match: { stock: { $gt: 0 } } },
// Stage 2: Group (like GROUP BY)
{ $group: {
_id: "$category",
averagePrice: { $avg: "$price" },
totalStock: { $sum: "$stock" },
productCount: { $sum: 1 },
averageRating: { $avg: "$ratings.average" }
}},
// Stage 3: Sort (like ORDER BY)
{ $sort: { averageRating: -1 } },
// Stage 4: Limit results
{ $limit: 5 }
]);Output:
[
{ _id: "stationery", averagePrice: 14.99, totalStock: 500, productCount: 1, averageRating: 4.8 },
{ _id: "electronics", averagePrice: 42.89, totalStock: 229, productCount: 2, averageRating: 4.35 },
{ _id: "furniture", averagePrice: 44.99, totalStock: 60, productCount: 1, averageRating: 4.1 }
]More Pipeline Stages
// $project — reshape documents (like SELECT)
db.products.aggregate([
{ $project: {
name: 1,
price: 1,
profitMargin: { $subtract: ["$price", "$cost"] },
categoryUpperCase: { $toUpper: "$category" }
}}
]);
// $unwind — flatten arrays
db.products.aggregate([
{ $unwind: "$tags" },
{ $group: { _id: "$tags", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]);
// $lookup — MongoDB equivalent of JOIN
db.orders.aggregate([
{ $lookup: {
from: "products",
localField: "product_id",
foreignField: "_id",
as: "product_details"
}},
{ $unwind: "$product_details" },
{ $project: {
order_date: 1,
"product_details.name": 1,
"product_details.price": 1,
quantity: 1
}}
]);Indexes in MongoDB
// Create a single field index
db.products.createIndex({ name: 1 }); // 1 = ascending, -1 = descending
// Create a compound index
db.products.createIndex({ category: 1, price: -1 });
// Create a text index for full-text search
db.products.createIndex({ name: "text", tags: "text" });
// Create a unique index
db.products.createIndex({ sku: 1 }, { unique: true });
// Explain query execution
db.products.find({ category: "electronics" }).explain("executionStats");When to Use MongoDB vs SQL
MongoDB Is Good For:
- Rapid prototyping and agile development
- Unstructured or varying data (different fields per document)
- Hierarchical data (nested documents instead of joins)
- Horizontal scaling (sharding built in)
- Large volumes of simple data (logs, events, metrics)
SQL Is Better For:
- Complex relationships and joins
- Strong data integrity requirements
- Complex transactions spanning multiple records
- Well-defined, stable schemas
- Reporting and analytical queries
| Aspect | MongoDB | SQL (MySQL/PostgreSQL) |
|---|---|---|
| Schema | Flexible, no schema | Rigid, predefined schema |
| Relationships | Embedded or references | Foreign keys + JOINs |
| Scaling | Horizontal (sharding) | Vertical (scale up) |
| Transactions | Multi-document (4.0+) | Full ACID |
| Query language | JavaScript-like | SQL |
| Use case | Real-time, big data | Financial, ERP, CRM |
Common MongoDB Mistakes
1. Creating Too Many Collections
MongoDB is document-based. Instead of creating separate collections for addresses, orders, and profiles (like you would with SQL tables), embed related data in a single document.
2. Not Using Indexes
Without indexes, MongoDB scans every document (collection scan). For collections with thousands of documents, this is slow. Always index fields used in queries.
3. Oversized Documents
MongoDB documents have a 16MB limit. While large, storing binary files (images, videos) directly in documents is inefficient. Use GridFS for files or store them in object storage with URLs in the document.
4. Ignoring the ObjectId Timestamp
ObjectIds contain a timestamp. You can sort by _id to get insertion order without a separate created_at field:
// Sort by insertion order
db.products.find().sort({ _id: -1 });
// Extract timestamp from ObjectId
db.products.find({
_id: { $gt: ObjectId("665000000000000000000000") } // Created after June 2026
});5. Using $ne and $nin on Indexed Fields
These operators perform poorly on indexed fields. Use $gt/$lt ranges instead when possible.
6. Not Understanding Write Concern
MongoDB offers configurable write concern — how many nodes must acknowledge a write before it’s considered successful. Lower values (w: 1) are faster but risk data loss. Higher values (w: majority) are safer but slower.
7. Deep Nesting Documents
While MongoDB supports nested documents, deep nesting (4+ levels) makes queries complex and slow. Flatten data or use references for deeply nested structures.
Common Mistakes Beginners Make
1. Skipping the Fundamentals
Many beginners jump straight to advanced topics without mastering the basics. Take time to understand the core concepts before moving on.
2. Not Practicing Enough
Reading tutorials without writing code leads to shallow understanding. Code along with every example and experiment on your own.
3. Ignoring Error Messages
Error messages tell you exactly what went wrong. Read them carefully — they usually point to the line and type of issue.
4. Copy-Pasting Without Understanding
It’s tempting to copy code from tutorials, but typing it yourself and understanding each line builds real skill.
5. Giving Up Too Early
Every developer hits frustrating bugs. Take breaks, ask for help, and remember that struggling is part of learning.
Practice Questions
1. What is a document in MongoDB?
A JSON-like data structure (BSON) that’s equivalent to a row in SQL. Documents can have different fields, nested objects, and arrays — no schema required.
2. How does MongoDB handle relationships?
Through embedded documents (nesting related data) or references (storing IDs of related documents). There are no JOINs — $lookup in the aggregation pipeline provides similar functionality.
3. What is the aggregation pipeline?
A framework for processing documents through sequential stages ($match, $group, $sort, $project, etc.), similar to Unix pipes or SQL’s GROUP BY and other clauses.
4. When should you embed vs reference in MongoDB?
Embed when data is always accessed together and doesn’t grow unbounded (e.g., addresses in a user profile). Reference when data grows independently or is shared across many documents (e.g., products in orders).
5. Challenge: Write an aggregation pipeline that finds the top 3 most common tags across all products.
db.products.aggregate([
{ $unwind: "$tags" },
{ $group: { _id: "$tags", count: { $sum: 1 } } },
{ $sort: { count: -1 } },
{ $limit: 3 }
]);Real-World Task: Build a Product Catalog
// Create a product catalog with embedded reviews
db.catalog.insertOne({
sku: "MOUSE-WL-001",
name: "Wireless Mouse",
category: "electronics",
price: 29.99,
variants: [
{ color: "black", stock: 50 },
{ color: "white", stock: 30 }
],
reviews: [
{ user: "alice", rating: 5, comment: "Great mouse!", date: ISODate() },
{ user: "bob", rating: 4, comment: "Good value", date: ISODate() }
],
specifications: {
connection: "Bluetooth 5.0",
battery: "AA (12 months)",
weight: "85g"
}
});
// Query: Find products with at least one review rating >= 4
db.catalog.find({
"reviews.rating": { $gte: 4 }
});
// Query: Find products with Bluetooth in specifications
db.catalog.find({
"specifications.connection": /Bluetooth/
});FAQ
Try It Yourself
Install MongoDB and run the examples:
# Install MongoDB Community Edition
# On Ubuntu:
wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo apt-key add -
echo "deb [ arch=amd64,arm64 ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install mongodb-org
# Start MongoDB
sudo systemctl start mongod
# Connect
mongosh// Inside mongosh, try these:
use shop;
db.products.insertOne({ name: "Test Product", price: 9.99 });
db.products.find();
db.products.createIndex({ price: 1 });
db.products.find({ price: { $gt: 5 } }).explain("executionStats");What’s Next
What’s Next
Congratulations on completing this Mongodb tutorial! Here’s where to go from here:
- Practice daily — Consistency is more important than long study sessions
- Build a project — Apply what you learned by building something real
- Explore related topics — Check out other tutorials in the same category
- Join the community — Discuss with other learners and share your progress
Remember: every expert was once a beginner. Keep coding!
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro