MongoDB logoMongoDBv8INTERMEDIATE

MongoDB

MongoDB cheat sheet with CRUD operations, query operators, aggregation pipelines, indexing, and schema design patterns with examples.

5 min read
mongodbdatabasenosqlaggregation

Sign in to mark items as known and track your progress.

Sign in

CRUD Operations

Create, Read, Update, and Delete documents in MongoDB

Insert Documents

Add new documents to a collection

javascript
// Insert one document
db.users.insertOne({
  name: "John Doe",
  email: "john@example.com",
  age: 30,
  created: new Date()
})

// Insert multiple documents
db.users.insertMany([
  { name: "Alice", age: 25 },
  { name: "Bob", age: 35 }
])
🟢 Essential - Every MongoDB app needs insert operations
💡 MongoDB automatically adds _id if not provided
⚡ insertMany() is faster than multiple insertOne()
📌 Returns insertedId(s) for tracking
⚠️ Check writeConcern for production apps
crudinsert

Find Documents

Query and retrieve documents from collections

javascript
// Find all documents
db.users.find()

// Find with filter
db.users.findOne({ email: "john@example.com" })

// Find multiple with conditions
db.users.find({ 
  age: { $gte: 18 },
  status: "active" 
})

// Projection (select fields)
db.users.find(
  { age: { $gte: 21 } },
  { name: 1, email: 1, _id: 0 }
)
🟢 Essential - Most common MongoDB operation
💡 findOne() returns first match only
📌 Use projection to reduce network transfer
⚡ Create indexes for frequently queried fields
🔗 Related: explain() to analyze query performance
crudreadquery

Update Documents

Modify existing documents in collections

javascript
// Update one document
db.users.updateOne(
  { email: "john@example.com" },
  { $set: { age: 31, modified: new Date() } }
)

// Update multiple documents
db.users.updateMany(
  { status: "inactive" },
  { $set: { status: "archived" } }
)

// Update or insert (upsert)
db.users.updateOne(
  { email: "new@example.com" },
  { $set: { name: "New User", age: 25 } },
  { upsert: true }
)
🟢 Essential - Keep data up-to-date
💡 Use $set to update specific fields only
⚠️ updateMany() can affect many documents - be careful
📌 upsert: true creates doc if not found
⚡ findOneAndUpdate() returns the document
crudupdate

Delete Documents

Remove documents from collections

javascript
// Delete one document
db.users.deleteOne({ email: "john@example.com" })

// Delete multiple documents
db.users.deleteMany({ status: "archived" })

// Delete all documents (careful!)
db.users.deleteMany({})
⚠️ Delete operations are permanent - no undo
💡 Consider soft delete for important data
📌 deleteMany({}) removes ALL documents
🟢 Essential - Clean up old/unused data
⚡ findOneAndDelete() returns deleted document
cruddelete

Query Operators

Powerful operators for filtering and matching documents

Comparison Operators

Compare field values in queries

javascript
// Equality
db.products.find({ price: 29.99 })
db.products.find({ category: { $eq: "electronics" } })

// Inequality
db.products.find({ price: { $ne: 0 } })

// Greater/Less than
db.products.find({ 
  price: { $gt: 20, $lte: 100 }  // 20 < price <= 100
})

// In/Not in array
db.products.find({ 
  category: { $in: ["electronics", "books"] }
})
db.products.find({ 
  status: { $nin: ["deleted", "archived"] }
})
🟢 Essential - Foundation of MongoDB queries
💡 $eq is implicit when using key: value
📌 $in is like SQL IN operator
⚡ Combine operators for complex queries
🔗 Related: $exists, $type for field checks
queryoperatorscomparison

Logical Operators

Combine multiple query conditions

javascript
// AND - all conditions must match
db.users.find({
  $and: [
    { age: { $gte: 18 } },
    { status: "active" },
    { emailVerified: true }
  ]
})

// OR - any condition can match
db.products.find({
  $or: [
    { category: "sale" },
    { price: { $lt: 20 } },
    { featured: true }
  ]
})

// NOT - invert condition
db.users.find({
  status: { $not: { $eq: "banned" } }
})

// NOR - none of the conditions
db.products.find({
  $nor: [
    { discontinued: true },
    { stock: 0 }
  ]
})
💡 Implicit AND when listing multiple fields
📌 $or requires array of conditions
⚡ $nor useful for exclusion logic
⚠️ Complex logic can impact performance
🔗 Related: $where for JavaScript expressions
queryoperatorslogical

Array Operators

Query and match array fields

javascript
// Match array containing value
db.posts.find({ tags: "mongodb" })

// Match array with all values
db.posts.find({ 
  tags: { $all: ["mongodb", "database"] }
})

// Match array by size
db.users.find({ 
  hobbies: { $size: 3 }
})

// Match array element
db.orders.find({
  "items.product": "laptop"
})
🟢 Essential for working with arrays
💡 Simple value matches any array element
📌 $elemMatch for complex array element conditions
⚡ Index array queries for better performance
⚠️ $size doesn't accept ranges (use $where)
queryoperatorsarrays

Text Search

Full-text search capabilities

javascript
// Create text index first
db.articles.createIndex({ 
  title: "text", 
  content: "text" 
})

// Basic text search
db.articles.find({ 
  $text: { $search: "mongodb tutorial" }
})

// Exact phrase search
db.articles.find({ 
  $text: { $search: '"exact phrase"' }
})

// Exclude terms
db.articles.find({ 
  $text: { $search: 'mongodb -sql' }
})
💡 Text index required for $text search
📌 $text searches all indexed fields
⚡ Text indexes can be large - use wisely
⚠️ Only one text index per collection
🔗 Consider Atlas Search for advanced needs
querysearchtext

Update Operators

Operators for modifying document fields and arrays

Field Update Operators

Modify document field values

javascript
// Set field values
db.users.updateOne(
  { _id: userId },
  { 
    $set: { name: "John", "address.city": "NYC" },
    $unset: { tempField: "" }
  }
)

// Increment/Decrement
db.products.updateOne(
  { _id: productId },
  { 
    $inc: { 
      views: 1,
      stock: -5 
    }
  }
)

// Multiply value
db.items.updateOne(
  { _id: itemId },
  { $mul: { price: 1.1 } }  // 10% increase
)
🟢 Essential - Most common update operations
💡 $set creates field if it doesn't exist
📌 Use dot notation for nested fields
⚡ $inc is atomic - safe for concurrent updates
⚠️ $unset removes field entirely
updateoperatorsfields

Array Update Operators

Modify array fields in documents

javascript
// Add to array
db.users.updateOne(
  { _id: userId },
  { 
    $push: { tags: "premium" },
    $addToSet: { hobbies: "reading" }  // No duplicates
  }
)

// Add multiple items
db.posts.updateOne(
  { _id: postId },
  { 
    $push: { 
      comments: { 
        $each: [comment1, comment2],
        $sort: { date: -1 },
        $slice: 10  // Keep only 10 newest
      }
    }
  }
)

// Remove from array
db.users.updateOne(
  { _id: userId },
  { 
    $pull: { tags: "old" },
    $pop: { history: -1 }  // Remove first (-1) or last (1)
  }
)
💡 $addToSet prevents duplicate values
📌 $ positional operator updates matched element
⚡ $push with $each for bulk array updates
⚠️ $pull removes ALL matching elements
🔗 Related: $pullAll, $pushAll (deprecated)
updateoperatorsarrays

Aggregation Pipeline

Transform and analyze data with pipeline stages

Basic Pipeline Stages

Common stages for data transformation

javascript
// Basic aggregation pipeline
db.orders.aggregate([
  { $match: { status: "completed" } },
  { $group: {
    _id: "$customerId",
    totalSpent: { $sum: "$total" },
    orderCount: { $sum: 1 }
  }},
  { $sort: { totalSpent: -1 } },
  { $limit: 10 }
])

// Project (reshape) documents
db.users.aggregate([
  { $project: {
    name: 1,
    email: 1,
    fullName: { $concat: ["$firstName", " ", "$lastName"] },
    age: { $subtract: [
      { $year: new Date() },
      { $year: "$birthDate" }
    ]}
  }}
])
🟢 Essential - Powerful data processing
💡 Pipeline stages process sequentially
⚡ $match early to reduce documents
📌 $group _id can be complex expression
🔗 Related: $facet for multiple pipelines
aggregationpipeline

Aggregation Operators

Operators for calculations and transformations

javascript
// Group accumulator operators
db.sales.aggregate([
  { $group: {
    _id: "$category",
    total: { $sum: "$amount" },
    average: { $avg: "$amount" },
    min: { $min: "$amount" },
    max: { $max: "$amount" },
    count: { $sum: 1 },
    items: { $push: "$item" },
    uniqueItems: { $addToSet: "$item" }
  }}
])

// String operators
{ $project: {
  upper: { $toUpper: "$name" },
  lower: { $toLower: "$name" },
  substring: { $substr: ["$name", 0, 3] },
  concat: { $concat: ["$first", " ", "$last"] }
}}
💡 $sum: 1 counts documents
📌 Use $$ for variables in expressions
⚡ $cond for if-then-else logic
🟢 Essential for data analysis
🔗 Related: $map, $reduce for array processing
aggregationoperators

Indexes & Performance

Optimize query performance with proper indexing

Index Types

Different index types for various use cases

javascript
// Single field index
db.users.createIndex({ email: 1 })  // 1 = ascending
db.posts.createIndex({ createdAt: -1 })  // -1 = descending

// Compound index (multiple fields)
db.orders.createIndex({ 
  customerId: 1, 
  createdAt: -1 
})

// Unique index
db.users.createIndex(
  { email: 1 }, 
  { unique: true }
)

// Text index for search
db.articles.createIndex({ 
  title: "text", 
  content: "text" 
})
🟢 Essential - Indexes make queries fast
💡 Compound indexes support multiple query patterns
⚠️ Too many indexes slow down writes
📌 Index order matters in compound indexes
⚡ Use explain() to verify index usage
indexesperformance

Query Optimization

Analyze and optimize query performance

javascript
// Explain query execution
db.users.find({ 
  age: { $gte: 18 } 
}).explain("executionStats")

// Check index usage
db.users.find({ email: "john@example.com" })
  .hint({ email: 1 })  // Force specific index
  .explain()

// Get index statistics
db.users.getIndexes()
db.users.totalIndexSize()
💡 explain() shows query execution plan
📌 "COLLSCAN" means no index used (slow)
⚡ Profiler helps find slow queries
⚠️ hint() forces index but use carefully
🔗 Related: MongoDB Compass for visual analysis
performanceoptimization

Schema Design & Validation

Design patterns and data validation strategies

Schema Validation

Enforce document structure and data types

javascript
// Create collection with validation
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "email", "age"],
      properties: {
        name: {
          bsonType: "string",
          description: "must be a string"
        },
        email: {
          bsonType: "string",
          pattern: "^[a-z0-9+_.-]+@[a-z0-9.-]+$"
        },
        age: {
          bsonType: "int",
          minimum: 18,
          maximum: 120
        }
      }
    }
  }
})
🟢 Essential - Ensure data integrity
💡 JSON Schema provides rich validation
📌 validationLevel controls when to validate
⚠️ Validation adds small performance overhead
🔗 Related: Mongoose for application-level validation
schemavalidation

Design Patterns

Common MongoDB schema design patterns

javascript
// Embedding pattern (denormalization)
{
  _id: ObjectId("..."),
  name: "John Doe",
  addresses: [
    { type: "home", street: "123 Main St", city: "NYC" },
    { type: "work", street: "456 Corp Ave", city: "NYC" }
  ]
}

// Reference pattern (normalization)
// Users collection
{ _id: userId, name: "John", orderIds: [order1, order2] }
// Orders collection  
{ _id: order1, customerId: userId, total: 99.99 }

// Hybrid pattern
{
  _id: postId,
  title: "MongoDB Tips",
  author: {  // Embed frequently needed data
    _id: authorId,
    name: "Jane Doe",
    avatar: "jane.jpg"
  },
  // Reference for full author details
  authorId: authorId
}
💡 Embed for 1:1 or 1:few relationships
📌 Reference for 1:many or many:many
⚡ Denormalization improves read performance
⚠️ Avoid unbounded arrays (use bucketing)
🟢 Essential - Choose pattern based on access patterns
schemapatternsdesign