home / skills / pluginagentmarketplace / custom-plugin-sql / mongodb

mongodb skill

/skills/mongodb

This skill helps you manage MongoDB data efficiently by guiding document modeling, CRUD, indexing, and aggregation best practices.

npx playbooks add skill pluginagentmarketplace/custom-plugin-sql --skill mongodb

Review the files below or copy the command above to add this skill to your agents.

Files (5)
SKILL.md
10.6 KB
---
name: mongodb
description: MongoDB fundamentals including document model, CRUD operations, querying, indexing, and aggregation framework for NoSQL database applications.
sasmp_version: "1.3.0"
bonded_agent: 03-mongodb
bond_type: PRIMARY_BOND
---

# MongoDB Mastery

## Document Model Basics

```javascript
// MongoDB document (JSON-like structure)
{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  firstName: "John",
  lastName: "Doe",
  email: "[email protected]",
  salary: 75000,
  department: "Engineering",
  skills: ["JavaScript", "Python", "SQL"],
  address: {
    street: "123 Main St",
    city: "New York",
    state: "NY"
  },
  joinDate: new Date("2023-01-15")
}
```

## Collection Operations

```javascript
// Create database and collection
use company_db

// Insert single document
db.employees.insertOne({
  firstName: "Jane",
  lastName: "Smith",
  email: "[email protected]",
  salary: 80000
})

// Insert multiple documents
db.employees.insertMany([
  { firstName: "Bob", lastName: "Johnson", salary: 70000 },
  { firstName: "Alice", lastName: "Williams", salary: 85000 }
])

// Get document count
db.employees.countDocuments({})

// Validate collection
db.employees.validate()
```

## CRUD Operations

```javascript
// READ - Basic find
db.employees.find()

// Find by condition
db.employees.find({ salary: { $gt: 75000 } })

// Find with projection (select specific fields)
db.employees.find(
  { department: "Engineering" },
  { firstName: 1, lastName: 1, salary: 1, _id: 0 }
)

// Find one document
db.employees.findOne({ email: "[email protected]" })

// UPDATE - Update one document
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $set: { salary: 90000 } }
)

// Update multiple documents
db.employees.updateMany(
  { department: "Engineering" },
  { $set: { bonus: 5000 } }
)

// DELETE - Delete documents
db.employees.deleteOne({ _id: ObjectId("...") })
db.employees.deleteMany({ department: "HR" })
```

## Query Operators

```javascript
// Comparison operators
db.employees.find({ salary: { $gt: 75000 } })      // Greater than
db.employees.find({ salary: { $gte: 75000 } })     // Greater than or equal
db.employees.find({ salary: { $lt: 75000 } })      // Less than
db.employees.find({ salary: { $lte: 75000 } })     // Less than or equal
db.employees.find({ salary: { $eq: 75000 } })      // Equal
db.employees.find({ salary: { $ne: 75000 } })      // Not equal

// Array operators
db.employees.find({ skills: "JavaScript" })        // Contains value
db.employees.find({ skills: { $in: ["Python", "Go"] } })    // Contains any
db.employees.find({ skills: { $all: ["JavaScript", "Python"] } })  // Contains all
db.employees.find({ skills: { $size: 3 } })        // Array size

// Element operators
db.employees.find({ phone: { $exists: true } })    // Field exists
db.employees.find({ salary: { $type: "number" } }) // Field type check

// String matching
db.employees.find({ email: { $regex: "gmail" } })  // Regular expression
```

## Sorting and Limiting

```javascript
// Sort by single field
db.employees.find().sort({ salary: -1 })           // Descending
db.employees.find().sort({ salary: 1 })            // Ascending

// Sort by multiple fields
db.employees.find().sort({ department: 1, salary: -1 })

// Limit and skip
db.employees.find().limit(10)                       // First 10 results
db.employees.find().skip(20).limit(10)              // Pagination
```

## Indexing

```javascript
// Create single field index
db.employees.createIndex({ email: 1 })

// Create unique index
db.employees.createIndex({ email: 1 }, { unique: true })

// Create compound index
db.employees.createIndex({ department: 1, salary: -1 })

// Create text index for search
db.employees.createIndex({ firstName: "text", lastName: "text" })

// List indexes
db.employees.getIndexes()

// Drop index
db.employees.dropIndex("email_1")

// Full text search with text index
db.employees.find({ $text: { $search: "john" } })
```

## Data Types

```javascript
// String
{ name: "John Doe" }

// Number (Int32, Int64, Double)
{ age: 30, salary: 75000.50 }

// Boolean
{ active: true }

// Date
{ createdDate: new Date() }

// Array
{ skills: ["JavaScript", "Python"] }

// Object/Embedded document
{ address: { city: "NYC", state: "NY" } }

// ObjectID
{ _id: ObjectId() }

// Null
{ phone: null }

// Regular Expression
{ email: /gmail/ }
```

## Bulk Operations

```javascript
// Initialize bulk operation
let bulk = db.employees.initializeUnorderedBulkOp()

// Add multiple operations
bulk.find({ department: "Engineering" }).update({ $set: { bonus: 5000 } })
bulk.find({ salary: { $lt: 50000 } }).update({ $inc: { salary: 2000 } })
bulk.insert({ firstName: "New", lastName: "Employee" })
bulk.find({ _id: ObjectId("...") }).removeOne()

// Execute bulk
bulk.execute()
```

## Aggregation Pipeline (Data Processing)

```javascript
// Basic pipeline stages
db.employees.aggregate([
  { $match: { salary: { $gt: 75000 } } },     // Filter
  { $group: {                                  // Group & aggregate
      _id: "$department",
      avgSalary: { $avg: "$salary" },
      count: { $sum: 1 }
  }},
  { $sort: { avgSalary: -1 } },                // Sort
  { $limit: 5 }                                // Limit results
])

// Projection stage (reshape documents)
db.employees.aggregate([
  { $project: {
      fullName: { $concat: ["$firstName", " ", "$lastName"] },
      salary: 1,
      yearing_salary: { $multiply: ["$salary", 12] },
      _id: 0
  }}
])

// Unwind arrays for analysis
db.employees.aggregate([
  { $unwind: "$skills" },                      // Expand skills array
  { $group: {
      _id: "$skills",
      count: { $sum: 1 }
  }},
  { $sort: { count: -1 } }
])

// Lookup (similar to SQL JOIN)
db.orders.aggregate([
  { $lookup: {
      from: "customers",
      localField: "customerId",
      foreignField: "_id",
      as: "customerInfo"
  }},
  { $unwind: "$customerInfo" },
  { $project: {
      orderId: 1,
      "customerInfo.name": 1,
      "customerInfo.email": 1,
      amount: 1
  }}
])

// Complex multi-stage pipeline
db.sales.aggregate([
  { $match: { date: { $gte: new Date("2023-01-01") } } },
  { $group: {
      _id: { month: { $month: "$date" }, year: { $year: "$date" } },
      totalSales: { $sum: "$amount" },
      avgSale: { $avg: "$amount" },
      ordersCount: { $sum: 1 }
  }},
  { $sort: { "_id.year": 1, "_id.month": 1 } },
  { $project: {
      month: "$_id.month",
      year: "$_id.year",
      totalSales: { $round: ["$totalSales", 2] },
      avgSale: { $round: ["$avgSale", 2] },
      ordersCount: 1,
      _id: 0
  }}
])
```

## Transactions (ACID)

```javascript
// Start a session
const session = db.getMongo().startSession()
session.startTransaction()

try {
  // Multiple operations in transaction
  db.accounts.updateOne(
    { _id: "account1" },
    { $inc: { balance: -100 } },
    { session: session }
  )

  db.accounts.updateOne(
    { _id: "account2" },
    { $inc: { balance: 100 } },
    { session: session }
  )

  // All succeed or all fail
  session.commitTransaction()
} catch (error) {
  session.abortTransaction()
  throw error
} finally {
  session.endSession()
}
```

## Update Operators

```javascript
// $set - set field value
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $set: { salary: 90000 } }
)

// $inc - increment field
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $inc: { salary: 5000 } }
)

// $push - add to array
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $push: { skills: "Kubernetes" } }
)

// $addToSet - add to array if not exists
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $addToSet: { skills: "Docker" } }
)

// $pull - remove from array
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $pull: { skills: "COBOL" } }
)

// $unset - remove field
db.employees.updateOne(
  { _id: ObjectId("...") },
  { $unset: { phone: "" } }
)

// Combination updates
db.employees.updateOne(
  { _id: ObjectId("...") },
  {
    $set: { updatedAt: new Date() },
    $inc: { salary: 5000 },
    $push: { performanceRatings: 4.5 }
  }
)
```

## Array Queries

```javascript
// Query array elements
db.employees.find({ skills: "Python" })        // Has Python skill

// Query array with conditions
db.employees.find({
  skills: { $elemMatch: { $eq: "JavaScript" } }
})

// Array position operators
db.orders.updateOne(
  { _id: ObjectId("..."), "items.sku": "SKU123" },
  { $set: { "items.$.quantity": 5 } }          // Update matching item
)

// Multiple array criteria
db.orders.find({
  items: { $elemMatch: {
    sku: "SKU123",
    quantity: { $gt: 3 }
  }}
})
```

## Real-World Examples

### E-commerce Product Catalog
```javascript
db.products.insertOne({
  _id: ObjectId(),
  sku: "PROD-001",
  name: "Laptop",
  price: 999.99,
  stock: 50,
  categories: ["Electronics", "Computers"],
  specs: {
    cpu: "Intel i7",
    ram: "16GB",
    storage: "512GB SSD"
  },
  reviews: [
    { userId: "user1", rating: 5, comment: "Great!" },
    { userId: "user2", rating: 4, comment: "Good value" }
  ],
  lastUpdated: new Date()
})

// Update stock with transaction
session.startTransaction()
db.products.updateOne({ sku: "PROD-001" }, { $inc: { stock: -1 } }, { session })
db.orders.insertOne({ productId: ObjectId(), quantity: 1 }, { session })
session.commitTransaction()
```

### User Profiles with Flexible Schema
```javascript
db.users.insertOne({
  _id: ObjectId(),
  username: "john_doe",
  email: "[email protected]",
  profile: {
    firstName: "John",
    lastName: "Doe",
    bio: "Software engineer",
    socialLinks: {
      github: "john-doe",
      twitter: "@johndoe"
    }
  },
  preferences: {
    theme: "dark",
    notifications: true,
    language: "en"
  },
  metadata: {
    createdAt: new Date(),
    lastLogin: new Date(),
    loginCount: 42
  }
})

// Flexible update - can add new fields
db.users.updateOne(
  { username: "john_doe" },
  { $set: { "profile.avatar": "url", "preferences.emailFrequency": "weekly" } }
)
```

## Performance Tips

```javascript
// Create indexes for common queries
db.employees.createIndex({ email: 1 })
db.employees.createIndex({ department: 1, salary: -1 })

// Use explain to optimize queries
db.employees.find({ salary: { $gt: 75000 } }).explain("executionStats")

// Projection to reduce data transfer
db.employees.find(
  { salary: { $gt: 75000 } },
  { firstName: 1, lastName: 1, salary: 1, _id: 0 }
)

// Batch writes for bulk inserts
db.employees.insertMany(largeArray, { ordered: false })

// Aggregation optimization (match early)
db.orders.aggregate([
  { $match: { status: "completed" } },        // Early filter
  { $lookup: { from: "customers", ... } },
  { $group: { _id: "$customerId", total: { $sum: "$amount" } } }
])
```

## Next Steps

Learn NoSQL design patterns, denormalization strategies, and advanced schema design in the `nosql-design` skill.

Overview

This skill teaches MongoDB fundamentals for building and optimizing NoSQL applications. It covers the document model, CRUD operations, querying, indexing, aggregation pipelines, transactions, and performance tips. Practical examples show patterns for real-world use like e-commerce catalogs and user profiles.

How this skill works

The skill inspects common MongoDB operations and patterns: document structure, collection CRUD, query operators, array handling, indexes, bulk writes, and transactions. It demonstrates how to construct queries, build aggregation pipelines, create indexes for performance, and apply update operators safely. Each topic includes concise examples and optimization guidance to apply immediately in projects.

When to use it

  • Designing flexible schemas for applications that require nested or arrayed data
  • Performing complex reporting or analytics using aggregation pipelines
  • Optimizing read/write performance with indexes and projection
  • Executing multi-document updates or consistency-sensitive flows with transactions
  • Bulk loading or migrating large datasets efficiently

Best practices

  • Model around application queries—embed for fast reads, reference for many-to-many relations
  • Create selective compound indexes for common query patterns and use explain() to validate
  • Filter early in aggregation pipelines and push $match/$limit as close to the source as possible
  • Use projection to return only needed fields and reduce network and memory overhead
  • Batch writes with insertMany or bulk operations for high-volume inserts and updates

Example use cases

  • E-commerce product catalog with embedded specs, reviews, and stock management using transactions for inventory updates
  • User profile store that supports flexible attributes and incremental schema evolution via $set and nested updates
  • Analytics pipelines to compute monthly sales, average order values, and top categories using $group, $sort, $project, and $lookup
  • Real-time skill or tag counts by unwinding arrays and grouping to power recommendations and search faceting
  • Bulk update employee records to add or adjust compensation fields using unordered bulk operations

FAQ

When should I embed data versus reference another collection?

Embed when the related data is accessed together and grows predictably; reference when the related data is large, shared across documents, or updated independently.

How do I choose indexes for optimal performance?

Start by identifying frequent query patterns and sort requirements, create compound indexes that match those patterns, then use explain("executionStats") to confirm index usage and adjust cardinality or key order as needed.