This guide provides comprehensive examples of all CRUD (Create, Read, Update, Delete) operations in MongoDB using the MongoDB Shell (mongosh).
Table of Contents
- Getting Started
- CREATE Operations
- READ Operations
- UPDATE Operations
- DELETE Operations
- Advanced Operations
- Indexes
- Aggregation Pipeline
Getting Started
Connect to MongoDB
# Connect to local MongoDB
mongosh
# Connect to specific database
mongosh myDatabase
# Connect with authentication
mongosh -u username -p password --authenticationDatabase admin
Basic Commands
// Show all databases
show dbs
// Switch to a database (creates if doesn't exist)
use myDatabase
// Show current database name
db
// Show all collections in current database
show collections
// Get database statistics
db.stats()
// Get collection statistics
db.collectionName.stats()
CREATE Operations
1. Insert Single Document
Syntax:
db.collectionName.insertOne(document)
Example:
// Insert a single user document
db.users.insertOne({
name: "John Doe",
age: 30,
email: "john@example.com",
city: "New York",
isActive: true,
createdAt: new Date()
})
// Output:
// {
// acknowledged: true,
// insertedId: ObjectId("507f1f77bcf86cd799439011")
// }
2. Insert Multiple Documents
Syntax:
db.collectionName.insertMany([document1, document2, ...])
Example:
// Insert multiple users
db.users.insertMany([
{
name: "Jane Smith",
age: 25,
email: "jane@example.com",
city: "Los Angeles",
isActive: true,
createdAt: new Date()
},
{
name: "Bob Johnson",
age: 35,
email: "bob@example.com",
city: "Chicago",
isActive: false,
createdAt: new Date()
},
{
name: "Alice Williams",
age: 28,
email: "alice@example.com",
city: "New York",
isActive: true,
createdAt: new Date()
}
])
// Output:
// {
// acknowledged: true,
// insertedIds: {
// '0': ObjectId("507f1f77bcf86cd799439012"),
// '1': ObjectId("507f1f77bcf86cd799439013"),
// '2': ObjectId("507f1f77bcf86cd799439014")
// }
// }
3. Insert with Custom _id
Example:
// Insert document with custom _id
db.users.insertOne({
_id: "user001",
name: "Charlie Brown",
age: 40,
email: "charlie@example.com"
})
// Note: _id must be unique. If it already exists, you'll get an error.
4. Insert Documents with Nested Objects
Example:
db.users.insertOne({
name: "David Lee",
age: 32,
email: "david@example.com",
address: {
street: "456 Oak Avenue",
city: "San Francisco",
state: "CA",
zipCode: "94102",
country: "USA"
},
contact: {
phone: "555-1234",
mobile: "555-5678"
},
createdAt: new Date()
})
5. Insert Documents with Arrays
Example:
db.users.insertOne({
name: "Emma Davis",
age: 27,
email: "emma@example.com",
hobbies: ["reading", "swimming", "coding", "traveling"],
skills: [
{ name: "Python", level: "expert" },
{ name: "JavaScript", level: "intermediate" },
{ name: "MongoDB", level: "beginner" }
],
tags: ["developer", "tech-enthusiast"],
createdAt: new Date()
})
6. Insert with Validation
Example:
// MongoDB will validate data types
db.users.insertOne({
name: "Frank Miller",
age: "thirty-five", // String instead of number
email: "frank@example.com"
})
// This will insert successfully, but age will be stored as string
// Always validate data in your application layer
7. Insert with Timestamps
Example:
db.users.insertOne({
name: "Grace Wilson",
age: 29,
email: "grace@example.com",
createdAt: new Date(),
updatedAt: new Date(),
timestamp: Date.now() // Unix timestamp in milliseconds
})
READ Operations
1. Find All Documents
Syntax:
db.collectionName.find()
Example:
// Get all users
db.users.find()
// Pretty print (formatted output)
db.users.find().pretty()
// Limit number of results
db.users.find().limit(5)
// Skip documents
db.users.find().skip(10)
// Combine limit and skip (pagination)
db.users.find().skip(0).limit(10) // First page
db.users.find().skip(10).limit(10) // Second page
2. Find One Document
Syntax:
db.collectionName.findOne(query)
Example:
// Find first document
db.users.findOne()
// Find specific document
db.users.findOne({ name: "John Doe" })
// Find by _id
db.users.findOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
3. Find with Query Filters
Equality Query
// Find users with specific age
db.users.find({ age: 30 })
// Find active users
db.users.find({ isActive: true })
// Find by email
db.users.find({ email: "john@example.com" })
Comparison Operators
// Greater than
db.users.find({ age: { $gt: 25 } }) // age > 25
// Greater than or equal
db.users.find({ age: { $gte: 30 } }) // age >= 30
// Less than
db.users.find({ age: { $lt: 30 } }) // age < 30
// Less than or equal
db.users.find({ age: { $lte: 30 } }) // age <= 30
// Not equal
db.users.find({ age: { $ne: 30 } }) // age != 30
// In array
db.users.find({ age: { $in: [25, 30, 35] } }) // age in [25, 30, 35]
// Not in array
db.users.find({ age: { $nin: [25, 30] } }) // age not in [25, 30]
// Multiple conditions
db.users.find({ age: { $gt: 25, $lt: 35 } }) // 25 < age < 35
Logical Operators
// AND (implicit)
db.users.find({ age: 30, isActive: true })
// AND (explicit)
db.users.find({ $and: [
{ age: { $gt: 25 } },
{ isActive: true }
]})
// OR
db.users.find({ $or: [
{ age: { $lt: 25 } },
{ age: { $gt: 35 } }
]})
// NOT
db.users.find({ $not: { age: { $gt: 30 } } })
// NOR (neither condition true)
db.users.find({ $nor: [
{ age: { $lt: 25 } },
{ isActive: false }
]})
Element Operators
// Field exists
db.users.find({ email: { $exists: true } })
// Field doesn't exist
db.users.find({ email: { $exists: false } })
// Type check
db.users.find({ age: { $type: "number" } })
db.users.find({ age: { $type: "string" } })
Array Operators
// All elements match
db.users.find({ hobbies: { $all: ["reading", "swimming"] } })
// Array size
db.users.find({ hobbies: { $size: 3 } })
// Element matches
db.users.find({ hobbies: "reading" }) // Array contains "reading"
// Array element at specific position
db.users.find({ "hobbies.0": "reading" }) // First element is "reading"
// Match array element with conditions
db.users.find({ "skills.level": "expert" })
String Operators
// Case-sensitive regex
db.users.find({ name: /John/ })
// Case-insensitive regex
db.users.find({ name: /john/i })
// Starts with
db.users.find({ name: /^John/ })
// Ends with
db.users.find({ name: /Doe$/ })
// Contains
db.users.find({ name: /.*John.*/ })
// Using $regex operator
db.users.find({ name: { $regex: "John", $options: "i" } })
Nested Document Queries
// Exact match (order matters)
db.users.find({ address: { city: "New York", state: "NY" } })
// Dot notation (recommended)
db.users.find({ "address.city": "New York" })
db.users.find({ "address.zipCode": "10001" })
// Nested conditions
db.users.find({ "address.city": { $in: ["New York", "Los Angeles"] } })
4. Projection (Select Specific Fields)
Syntax:
db.collectionName.find(query, projection)
Example:
// Include specific fields
db.users.find({}, { name: 1, email: 1, age: 1 })
// Exclude specific fields
db.users.find({}, { password: 0, _id: 0 })
// Mix include/exclude (only _id can be excluded with includes)
db.users.find({}, { name: 1, email: 1, _id: 0 })
// Project nested fields
db.users.find({}, { name: 1, "address.city": 1, "address.state": 1 })
5. Sorting
Syntax:
db.collectionName.find().sort({ field: 1 }) // 1 = ascending, -1 = descending
Example:
// Sort by age ascending
db.users.find().sort({ age: 1 })
// Sort by age descending
db.users.find().sort({ age: -1 })
// Sort by multiple fields
db.users.find().sort({ city: 1, age: -1 }) // Sort by city, then age
// Combine with other operations
db.users.find({ isActive: true })
.sort({ age: -1 })
.limit(10)
6. Count Documents
Syntax:
db.collectionName.countDocuments(query)
Example:
// Count all documents
db.users.countDocuments()
// Count with query
db.users.countDocuments({ age: { $gt: 30 } })
// Count active users
db.users.countDocuments({ isActive: true })
7. Distinct Values
Syntax:
db.collectionName.distinct(field)
Example:
// Get distinct cities
db.users.distinct("city")
// Get distinct values with query
db.users.distinct("city", { isActive: true })
8. Advanced Query Examples
// Complex query combining multiple operators
db.users.find({
$and: [
{ age: { $gte: 25, $lte: 40 } },
{ isActive: true },
{ $or: [
{ "address.city": "New York" },
{ "address.city": "Los Angeles" }
]},
{ hobbies: { $in: ["reading", "coding"] } }
]
}).sort({ age: 1 }).limit(20)
// Query with regex and array
db.users.find({
name: { $regex: /^J/, $options: "i" },
hobbies: { $size: { $gt: 2 } }
})
UPDATE Operations
1. Update One Document
Syntax:
db.collectionName.updateOne(filter, update, options)
Example:
// Update single field
db.users.updateOne(
{ name: "John Doe" },
{ $set: { age: 31 } }
)
// Update multiple fields
db.users.updateOne(
{ email: "john@example.com" },
{ $set: { age: 31, city: "Boston" } }
)
// Output:
// {
// acknowledged: true,
// matchedCount: 1,
// modifiedCount: 1,
// upsertedId: null
// }
2. Update Multiple Documents
Syntax:
db.collectionName.updateMany(filter, update, options)
Example:
// Update all active users
db.users.updateMany(
{ isActive: true },
{ $set: { lastLogin: new Date() } }
)
// Increment age for all users
db.users.updateMany(
{},
{ $inc: { age: 1 } }
)
3. Replace Document
Syntax:
db.collectionName.replaceOne(filter, replacement)
Example:
// Replace entire document (except _id)
db.users.replaceOne(
{ name: "John Doe" },
{
name: "John Doe",
age: 32,
email: "john.doe@example.com",
city: "Boston",
isActive: true,
updatedAt: new Date()
}
)
4. Update Operators
$set - Set Field Value
// Set single field
db.users.updateOne(
{ name: "John Doe" },
{ $set: { city: "Boston" } }
)
// Set nested field
db.users.updateOne(
{ name: "John Doe" },
{ $set: { "address.city": "Boston" } }
)
// Set multiple fields
db.users.updateOne(
{ name: "John Doe" },
{ $set: { city: "Boston", age: 31, isActive: true } }
)
$unset - Remove Field
// Remove field
db.users.updateOne(
{ name: "John Doe" },
{ $unset: { middleName: "" } }
)
// Remove nested field
db.users.updateOne(
{ name: "John Doe" },
{ $unset: { "address.zipCode": "" } }
)
$inc - Increment/Decrement
// Increment by 1
db.users.updateOne(
{ name: "John Doe" },
{ $inc: { age: 1 } }
)
// Increment by specific amount
db.users.updateOne(
{ name: "John Doe" },
{ $inc: { age: 5 } }
)
// Decrement
db.users.updateOne(
{ name: "John Doe" },
{ $inc: { age: -1 } }
)
// Increment multiple fields
db.users.updateOne(
{ name: "John Doe" },
{ $inc: { age: 1, loginCount: 1 } }
)
$mul - Multiply
// Multiply field value
db.users.updateOne(
{ name: "John Doe" },
{ $mul: { age: 1.1 } } // Increase age by 10%
)
$min / $max - Set Minimum/Maximum
// Set minimum value
db.users.updateOne(
{ name: "John Doe" },
{ $min: { age: 25 } } // Only update if current age < 25
)
// Set maximum value
db.users.updateOne(
{ name: "John Doe" },
{ $max: { age: 50 } } // Only update if current age > 50
)
$rename - Rename Field
// Rename field
db.users.updateOne(
{ name: "John Doe" },
{ $rename: { "city": "location" } }
)
// Rename nested field
db.users.updateOne(
{ name: "John Doe" },
{ $rename: { "address.street": "address.streetAddress" } }
)
Array Update Operators
$push - Add to Array
// Add single element
db.users.updateOne(
{ name: "John Doe" },
{ $push: { hobbies: "gaming" } }
)
// Add multiple elements
db.users.updateOne(
{ name: "John Doe" },
{ $push: { hobbies: { $each: ["gaming", "photography"] } } }
)
// Add with position
db.users.updateOne(
{ name: "John Doe" },
{ $push: { hobbies: { $each: ["gaming"], $position: 0 } } }
)
// Add with conditions
db.users.updateOne(
{ name: "John Doe" },
{ $push: { hobbies: { $each: ["gaming"], $slice: 5 } } } // Keep only 5 elements
)
$addToSet - Add if Not Exists
// Add only if not already in array
db.users.updateOne(
{ name: "John Doe" },
{ $addToSet: { hobbies: "reading" } }
)
// Add multiple unique values
db.users.updateOne(
{ name: "John Doe" },
{ $addToSet: { hobbies: { $each: ["gaming", "photography"] } } }
)
$pop - Remove from Array
// Remove last element
db.users.updateOne(
{ name: "John Doe" },
{ $pop: { hobbies: 1 } }
)
// Remove first element
db.users.updateOne(
{ name: "John Doe" },
{ $pop: { hobbies: -1 } }
)
$pull - Remove Matching Elements
// Remove specific value
db.users.updateOne(
{ name: "John Doe" },
{ $pull: { hobbies: "reading" } }
)
// Remove matching condition
db.users.updateOne(
{ name: "John Doe" },
{ $pull: { skills: { level: "beginner" } } }
)
// Remove multiple values
db.users.updateOne(
{ name: "John Doe" },
{ $pull: { hobbies: { $in: ["reading", "swimming"] } } }
)
$pullAll - Remove All Matching Values
db.users.updateOne(
{ name: "John Doe" },
{ $pullAll: { hobbies: ["reading", "swimming"] } }
)
Update Array Elements
// Update element at specific index
db.users.updateOne(
{ name: "John Doe" },
{ $set: { "hobbies.0": "new hobby" } }
)
// Update all matching array elements
db.users.updateOne(
{ name: "John Doe", "skills.name": "Python" },
{ $set: { "skills.$.level": "expert" } } // $ refers to matched element
)
// Update all array elements
db.users.updateOne(
{ name: "John Doe" },
{ $set: { "hobbies.$[]": "updated" } } // Updates all elements
)
5. Upsert (Insert if Not Exists)
Syntax:
db.collectionName.updateOne(filter, update, { upsert: true })
Example:
// Update if exists, insert if not
db.users.updateOne(
{ email: "newuser@example.com" },
{
$set: {
name: "New User",
age: 25,
email: "newuser@example.com",
createdAt: new Date()
}
},
{ upsert: true }
)
6. Update Options
// Update with options
db.users.updateOne(
{ name: "John Doe" },
{ $set: { age: 31 } },
{
upsert: true, // Insert if not found
writeConcern: { w: 1 } // Write concern
}
)
DELETE Operations
1. Delete One Document
Syntax:
db.collectionName.deleteOne(filter)
Example:
// Delete single document
db.users.deleteOne({ name: "John Doe" })
// Delete by _id
db.users.deleteOne({ _id: ObjectId("507f1f77bcf86cd799439011") })
// Output:
// {
// acknowledged: true,
// deletedCount: 1
// }
2. Delete Multiple Documents
Syntax:
db.collectionName.deleteMany(filter)
Example:
// Delete all inactive users
db.users.deleteMany({ isActive: false })
// Delete users older than 50
db.users.deleteMany({ age: { $gt: 50 } })
// Delete all documents (be careful!)
db.users.deleteMany({})
3. Find and Delete
Syntax:
db.collectionName.findOneAndDelete(filter, options)
Example:
// Find and delete, return deleted document
db.users.findOneAndDelete({ name: "John Doe" })
// With options
db.users.findOneAndDelete(
{ age: { $gt: 50 } },
{ sort: { age: -1 } } // Delete oldest first
)
Advanced Operations
1. Bulk Operations
// Bulk write operations
db.users.bulkWrite([
{ insertOne: { document: { name: "User1", age: 20 } } },
{ updateOne: { filter: { name: "User2" }, update: { $set: { age: 25 } } } },
{ deleteOne: { filter: { name: "User3" } } },
{ replaceOne: { filter: { name: "User4" }, replacement: { name: "User4", age: 30 } } }
])
2. Transactions (MongoDB 4.0+)
// Start a session
const session = db.getMongo().startSession()
// Start transaction
session.startTransaction()
try {
// Operations within transaction
session.getDatabase("myDatabase").users.insertOne({ name: "User1" })
session.getDatabase("myDatabase").users.updateOne(
{ name: "User2" },
{ $set: { age: 25 } }
)
// Commit transaction
session.commitTransaction()
} catch (error) {
// Abort transaction on error
session.abortTransaction()
} finally {
session.endSession()
}
3. Text Search
// Create text index
db.users.createIndex({ name: "text", email: "text" })
// Text search
db.users.find({ $text: { $search: "John" } })
// Text search with score
db.users.find(
{ $text: { $search: "John" } },
{ score: { $meta: "textScore" } }
).sort({ score: { $meta: "textScore" } })
Indexes
1. Create Index
// Single field index
db.users.createIndex({ email: 1 }) // 1 = ascending, -1 = descending
// Compound index
db.users.createIndex({ name: 1, age: -1 })
// Unique index
db.users.createIndex({ email: 1 }, { unique: true })
// Sparse index (only indexes documents with the field)
db.users.createIndex({ middleName: 1 }, { sparse: true })
// TTL index (auto-delete after expiration)
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
// Text index
db.users.createIndex({ name: "text", bio: "text" })
2. List Indexes
// Show all indexes
db.users.getIndexes()
// Show index size
db.users.totalIndexSize()
3. Drop Index
// Drop specific index
db.users.dropIndex({ email: 1 })
// Drop all indexes (except _id)
db.users.dropIndexes()
4. Explain Query
// Analyze query execution
db.users.find({ age: { $gt: 30 } }).explain()
// Execution stats
db.users.find({ age: { $gt: 30 } }).explain("executionStats")
Aggregation Pipeline
Basic Aggregation
// Simple aggregation
db.users.aggregate([
{ $match: { isActive: true } },
{ $group: { _id: "$city", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
])
Common Aggregation Stages
// $match - Filter documents
db.users.aggregate([
{ $match: { age: { $gt: 25 } } }
])
// $group - Group documents
db.users.aggregate([
{ $group: {
_id: "$city",
totalUsers: { $sum: 1 },
avgAge: { $avg: "$age" },
maxAge: { $max: "$age" },
minAge: { $min: "$age" }
}}
])
// $project - Reshape documents
db.users.aggregate([
{ $project: { name: 1, email: 1, age: 1 } }
])
// $sort - Sort documents
db.users.aggregate([
{ $sort: { age: -1 } }
])
// $limit - Limit results
db.users.aggregate([
{ $limit: 10 }
])
// $skip - Skip documents
db.users.aggregate([
{ $skip: 10 }
])
// $unwind - Deconstruct array
db.users.aggregate([
{ $unwind: "$hobbies" }
])
// $lookup - Join collections
db.orders.aggregate([
{ $lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}}
])
Complex Aggregation Example
// Get statistics by city
db.users.aggregate([
// Stage 1: Filter active users
{ $match: { isActive: true } },
// Stage 2: Group by city
{ $group: {
_id: "$city",
totalUsers: { $sum: 1 },
avgAge: { $avg: "$age" },
users: { $push: { name: "$name", age: "$age" } }
}},
// Stage 3: Sort by total users
{ $sort: { totalUsers: -1 } },
// Stage 4: Limit to top 5
{ $limit: 5 },
// Stage 5: Reshape output
{ $project: {
city: "$_id",
totalUsers: 1,
avgAge: { $round: ["$avgAge", 2] },
_id: 0
}}
])
Best Practices for mongosh
-
Always use pretty() for readability
javascript db.users.find().pretty() -
Use projection to limit returned data
javascript db.users.find({}, { name: 1, email: 1 }) -
Create indexes for frequently queried fields
javascript db.users.createIndex({ email: 1 }) -
Use explain() to analyze query performance
javascript db.users.find({ age: { $gt: 30 } }).explain("executionStats") -
Be careful with updateMany and deleteMany - Always test with find() first - Use transactions for multiple related operations
-
Use bulk operations for multiple writes
javascript db.users.bulkWrite([...])
Practice Exercises
-
Create a collection called "products" and insert 10 products with fields: name, price, category, stock, createdAt
-
Find all products in a specific category
-
Update the price of all products in a category by 10%
-
Find products with stock less than 10
-
Delete all products with price less than $5
-
Create an index on the "category" field
-
Use aggregation to find average price by category
Happy Learning! 🚀