SQL / NoSQL — MongoDB

MongoDB

The most popular NoSQL database — stores data as flexible JSON-like documents instead of rows and tables. Fast to query, easy to scale, schema-free by design.

NoSQL Document DB v4.2 – 7.x ~40 min read
9Topics
CRUDFull Coverage
Aggr.Pipelines
IndexOptimization
SQL↔Comparison
Document Database — Flexible, Scalable, Fast
MongoDB stores data as BSON documents (Binary JSON) inside collections — not rows in tables. No fixed schema means you can store differently shaped data in the same collection. Perfect for modern apps that need flexibility and horizontal scale.
SQL (Relational)
  • Data in tables with rows & columns
  • Fixed schema — ALTER TABLE to change
  • JOINs to relate data across tables
  • ACID transactions by default
  • Best for structured, relational data
MongoDB (NoSQL)
  • Data in collections of documents
  • Flexible schema — add fields anytime
  • $lookup for joins; embed related data instead
  • Multi-document transactions since v4.0
  • Best for hierarchical, fast-changing data
The key mental shift: instead of spreading data across multiple tables with JOINs, MongoDB encourages embedding related data in one document — so one read gets everything you need.
2009
Released
Built by 10gen, now MongoDB Inc.
#1
Most Popular NoSQL
Consistently top-ranked document DB
BSON
Storage Format
Binary JSON — faster to parse, more types
Atlas
Cloud Platform
Free tier available — deploy in seconds
Database & Collection Commands
MongoDB organises data as: Database → Collections → Documents. Think of a database as a schema, a collection as a table, and a document as a row — except documents are flexible JSON objects.
mongodb shell
// View all databases show dbs // Create or switch to a database use dbName // View the current database db // Delete the current database db.dropDatabase()
mongodb shell
// Show all collections in current DB show collections // Create a collection explicitly db.createCollection('comments') // Drop (delete) a collection db.comments.drop() // Note: collections are also created automatically // when you first insert a document into them
In MongoDB, databases and collections are created lazily — they appear the moment you insert the first document. use dbName doesn't create anything until data is written.
CRUD — Create, Read, Update, Delete
All examples use a comments collection. Documents are plain JSON objects — any shape, any fields.
mongodb shell
// Insert one document db.comments.insertOne({ name: 'Harry', lang: 'JavaScript', member_since: 5 }) // Insert many documents db.comments.insertMany([ { name: 'Harry', lang: 'JavaScript', member_since: 5 }, { name: 'Rohan', lang: 'Python', member_since: 3 }, { name: 'Lovish', lang: 'Java', member_since: 4 } ])
mongodb shell
// Show ALL documents db.comments.find() db.comments.find().pretty() // formatted output // Find first document matching a filter db.comments.findOne({ name: 'Harry' }) // Search by field value db.comments.find({ lang: 'Python' }) // Limit results db.comments.find().limit(2) // Skip + limit (pagination) db.comments.find().skip(2).limit(2) // Count matching documents db.comments.countDocuments({ lang: 'Python' }) // Projection — select specific fields (1 = include, 0 = exclude) db.comments.find({}, { name: 1, lang: 1, _id: 0 }) // Sort ascending (1) or descending (-1) db.comments.find().sort({ member_since: 1 }) // ascending db.comments.find().sort({ member_since: -1 }) // descending
mongodb shell
// Delete ONE matching document db.comments.deleteOne({ name: 'Harry' }) // Delete ALL matching documents db.comments.deleteMany({ lang: 'Java' })
Query Operators
Filter documents with powerful operators. All operators start with $ — MongoDB's way of distinguishing built-in keywords from field names.
$lt
Less than
member_since: {$lt: 90}
$lte
Less than or equal
member_since: {$lte: 90}
$gt
Greater than
member_since: {$gt: 2}
$gte
Greater than or equal
member_since: {$gte: 3}
$eq
Equal to (explicit)
lang: {$eq: "Python"}
$ne
Not equal to
member_since: {$ne: 5}
$in
Matches any value in array
lang: {$in: ["Python","Java"]}
$nin
Matches none in array
lang: {$nin: ["C++","Rust"]}
mongodb shell — comparison examples
db.comments.find({ member_since: { $lt: 90 } }) // less than 90 db.comments.find({ member_since: { $gt: 2 } }) // greater than 2 db.comments.find({ member_since: { $ne: 5 } }) // not equal to 5 db.comments.find({ lang: { $in: ['Python', 'Java'] } }) // in list db.comments.find({ lang: { $nin: ['C++', 'Rust'] } }) // not in list
mongodb shell
// $and — both conditions must match db.comments.find({ $and: [ { lang: 'Python' }, { member_since: { $gt: 2 } } ] }) // $or — either condition matches db.comments.find({ $or: [ { lang: 'Python' }, { lang: 'Java' } ] }) // Shorthand for $or on same field — use $in instead db.comments.find({ lang: { $in: ['Python', 'Java'] } })
Update Commands
Update operators let you modify specific fields without replacing the whole document. Always use an update operator like $set — otherwise you'll replace the entire document.
mongodb shell
// Update ONE document — $set changes specific fields db.comments.updateOne( { name: 'Shubham' }, { $set: { name: 'Harry', lang: 'JavaScript', member_since: 51 } }, { upsert: true } // create if not found ) // Update MANY documents matching the filter db.comments.updateMany( { lang: 'JavaScript' }, { $set: { verified: true } } )
mongodb shell
// $inc — increment (or decrement) a numeric field db.comments.updateOne( { name: 'Rohan' }, { $inc: { member_since: 2 } } // adds 2 to member_since ) // $rename — rename a field db.comments.updateOne( { name: 'Rohan' }, { $rename: { member_since: 'member' } } ) // $unset — remove a field entirely db.comments.updateOne( { name: 'Harry' }, { $unset: { verified: '' } } ) // $push — add item to an array field db.comments.updateOne( { name: 'Harry' }, { $push: { tags: 'mongodb' } } )
Never run db.collection.updateOne(filter, document) without an operator like $set. Without it, you replace the entire document with whatever you pass — deleting all other fields.
Indexes — Make Queries Fast
Without an index, MongoDB does a collection scan — reading every document to find matches. An index on a field lets MongoDB jump directly to results. Always index fields you frequently filter or sort on.
mongodb shell
// Create a single-field index (1 = ascending, -1 = descending) db.comments.createIndex({ name: 1 }) // Create a compound index (multiple fields) db.comments.createIndex({ lang: 1, member_since: -1 }) // Create a unique index db.comments.createIndex({ email: 1 }, { unique: true }) // View all indexes on a collection db.comments.getIndexes() // Drop a specific index db.comments.dropIndex({ name: 1 }) // Analyze query performance (uses index or collection scan?) db.comments.find({ name: 'Harry' }).explain('executionStats')
MongoDB automatically creates an index on _id for every collection. Always check .explain() on slow queries — if you see COLLSCAN instead of IXSCAN, you need an index.
Aggregation Pipeline
The aggregation pipeline transforms documents through a sequence of stages — filter, group, sort, reshape. Far more powerful than simple find() for analytics and reporting.
mongodb shell
// Count documents grouped by language db.comments.aggregate([ { $group: { _id: '$lang', total: { $sum: 1 } } } ]) // Average member_since by language db.comments.aggregate([ { $group: { _id: '$lang', avgExperience: { $avg: '$member_since' } }} ])
mongodb shell
// Filter → Group → Sort → Limit db.comments.aggregate([ // Stage 1: filter documents first { $match: { member_since: { $gte: 3 } } }, // Stage 2: group and count { $group: { _id: '$lang', count: { $sum: 1 }, avgYears: { $avg: '$member_since' }, maxYears: { $max: '$member_since' } }}, // Stage 3: sort by count descending { $sort: { count: -1 } }, // Stage 4: take top 3 { $limit: 3 } ])
$match
Filter documents (like find)
{ $match: { active: true } }
$group
Group by field, compute totals
{ $group: { _id: "$lang" } }
$sort
Sort by field(s)
{ $sort: { count: -1 } }
$limit
Limit number of results
{ $limit: 10 }
$skip
Skip N documents
{ $skip: 20 }
$project
Select/rename/compute fields
{ $project: { name: 1 } }
$lookup
Left-join another collection
{ $lookup: { from: "..." } }
$unwind
Deconstruct array field
{ $unwind: "$tags" }
Quick Reference — All Commands
Every command from this guide in one scannable table.
CommandWhat It Does
show dbsList all databases
use dbNameSwitch to (or create) a database
db.dropDatabase()Delete the current database
show collectionsList all collections in current DB
db.createCollection('name')Create a collection explicitly
db.col.drop()Delete a collection
db.col.insertOne({...})Insert a single document
db.col.insertMany([...])Insert multiple documents
db.col.find()Get all documents
db.col.find({field: val})Filter documents by field value
db.col.findOne({filter})Get first matching document
db.col.find().limit(n)Limit results to n documents
db.col.find().skip(n).limit(n)Paginate results
db.col.find().sort({field: 1})Sort ascending (1) or descending (-1)
db.col.countDocuments({filter})Count matching documents
db.col.updateOne(f, {$set:{...}})Update one document's fields
db.col.updateMany(f, {$set:{...}})Update all matching documents
db.col.deleteOne({filter})Delete first matching document
db.col.deleteMany({filter})Delete all matching documents
db.col.createIndex({field: 1})Create an index on a field
db.col.getIndexes()List all indexes
db.col.dropIndex({field: 1})Remove an index
db.col.aggregate([...])Run aggregation pipeline
Test Your MongoDB Knowledge
5 questions covering core MongoDB concepts. Click an option to check instantly.
1In MongoDB terminology, what is the equivalent of a SQL table?
2What does { $gt: 5 } mean in a MongoDB query filter?
3What is the danger of running db.col.updateOne(filter, document) without a $set operator?
4What does adding { upsert: true } to updateOne() do?
5Without an index on a queried field, MongoDB performs a _____ — reading every document to find matches.
Keep practicing!