MongoDB logoMongoDBv8INTERMEDIATE

MongoDB

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

5 min read
mongodbdatabasenosqlaggregation
Loading your progress

CRUD Operations

Create, Read, Update, and Delete documents in MongoDB

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

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

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

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

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

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

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

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

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

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

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