Agent skill

MongoDB

Use MongoDB for document-based NoSQL storage with flexible schemas, horizontal scaling, and rich querying.

Stars 10
Forks 1

Install this agent skill to your Project

npx add-skill https://github.com/hivellm/rulebook/tree/main/templates/skills/services/mongodb

SKILL.md

MongoDB Database Instructions

CRITICAL: Use MongoDB for document-based NoSQL storage with flexible schemas, horizontal scaling, and rich querying.

Core Features

Connection

typescript
// Using mongodb driver
import { MongoClient } from 'mongodb'

const client = new MongoClient(process.env.MONGODB_URI || 'mongodb://localhost:27017', {
  maxPoolSize: 10,
  minPoolSize: 2,
  maxIdleTimeMS: 30000,
  serverSelectionTimeoutMS: 5000,
})

await client.connect()
const db = client.db(process.env.DB_NAME || 'myapp')

// Using Mongoose
import mongoose from 'mongoose'

await mongoose.connect(process.env.MONGODB_URI, {
  maxPoolSize: 10,
  minPoolSize: 2,
  bufferCommands: false,
  bufferMaxEntries: 0,
})

Basic Operations

typescript
// Insert
const result = await db.collection('users').insertOne({
  name: 'John Doe',
  email: 'john@example.com',
  createdAt: new Date(),
})

// Insert many
await db.collection('users').insertMany([
  { name: 'User 1', email: 'user1@example.com' },
  { name: 'User 2', email: 'user2@example.com' },
])

// Find
const user = await db.collection('users').findOne({ email: 'john@example.com' })
const users = await db.collection('users').find({ active: true }).toArray()

// Update
await db.collection('users').updateOne(
  { email: 'john@example.com' },
  { $set: { name: 'Jane Doe', updatedAt: new Date() } }
)

// Update many
await db.collection('users').updateMany(
  { active: false },
  { $set: { status: 'inactive' } }
)

// Delete
await db.collection('users').deleteOne({ email: 'john@example.com' })
await db.collection('users').deleteMany({ active: false })

Advanced Queries

typescript
// Aggregation pipeline
const result = await db.collection('orders').aggregate([
  { $match: { status: 'completed' } },
  { $group: { _id: '$userId', total: { $sum: '$amount' } } },
  { $sort: { total: -1 } },
  { $limit: 10 },
]).toArray()

// Text search
await db.collection('articles').createIndex({ title: 'text', content: 'text' })
const results = await db.collection('articles').find({
  $text: { $search: 'search term' },
}).toArray()

// Geospatial queries
await db.collection('locations').createIndex({ location: '2dsphere' })
const nearby = await db.collection('locations').find({
  location: {
    $near: {
      $geometry: { type: 'Point', coordinates: [longitude, latitude] },
      $maxDistance: 1000, // meters
    },
  },
}).toArray()

// Array operations
await db.collection('users').find({
  tags: { $in: ['javascript', 'typescript'] },
})
await db.collection('users').updateOne(
  { email: 'john@example.com' },
  { $push: { tags: 'new-tag' } }
)

Common Patterns

Mongoose Schemas

typescript
import mongoose, { Schema } from 'mongoose'

const userSchema = new Schema({
  name: { type: String, required: true },
  email: { type: String, required: true, unique: true, index: true },
  age: { type: Number, min: 0, max: 120 },
  tags: [String],
  metadata: { type: Schema.Types.Mixed },
  createdAt: { type: Date, default: Date.now },
  updatedAt: { type: Date, default: Date.now },
})

userSchema.pre('save', function(next) {
  this.updatedAt = new Date()
  next()
})

const User = mongoose.model('User', userSchema)

Transactions

typescript
const session = client.startSession()
try {
  await session.withTransaction(async () => {
    await db.collection('accounts').updateOne(
      { userId: userId },
      { $inc: { balance: -100 } },
      { session }
    )
    
    await db.collection('transactions').insertOne(
      { userId, amount: -100, type: 'debit' },
      { session }
    )
  })
} finally {
  await session.endSession()
}

Indexing

typescript
// Create indexes
await db.collection('users').createIndex({ email: 1 }, { unique: true })
await db.collection('users').createIndex({ name: 1, email: 1 })
await db.collection('users').createIndex({ createdAt: -1 })

// Compound index
await db.collection('posts').createIndex({ authorId: 1, createdAt: -1 })

// TTL index (auto-delete after time)
await db.collection('sessions').createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 3600 }
)

Best Practices

DO:

  • Use connection pooling (10-20 connections)
  • Create indexes on frequently queried fields
  • Use transactions for multi-document operations
  • Use $set for updates (don't replace entire documents)
  • Use projection to limit returned fields
  • Use aggregation pipeline for complex queries
  • Enable replica sets for production
  • Use sharding for large datasets
  • Monitor slow queries
  • Use appropriate data types (ObjectId, Date, etc.)

DON'T:

  • Store large binary data (use GridFS)
  • Create too many indexes (affects write performance)
  • Use $where (slow, use aggregation instead)
  • Skip error handling
  • Hardcode connection strings
  • Ignore connection pool limits
  • Use nested arrays deeply (limit to 2-3 levels)
  • Skip validation
  • Ignore query performance
  • Store sensitive data without encryption

Configuration

Environment Variables

bash
MONGODB_URI=mongodb://localhost:27017/myapp
MONGODB_URI=mongodb://user:password@host:27017/database?authSource=admin
MONGODB_URI=mongodb+srv://user:password@cluster.mongodb.net/database

Docker Compose

yaml
services:
  mongodb:
    image: mongo:7
    ports:
      - "27017:27017"
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: securepassword
      MONGO_INITDB_DATABASE: myapp
    volumes:
      - mongodb_data:/data/db
    healthcheck:
      test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  mongodb_data:

Integration with Development

Testing

typescript
// Use test database
const testClient = new MongoClient('mongodb://localhost:27017/test_db')
await testClient.connect()
const testDb = testClient.db('test_db')

// Clean up after tests
afterEach(async () => {
  await testDb.collection('users').deleteMany({})
  await testDb.collection('posts').deleteMany({})
})

// Use transactions for test isolation
beforeEach(async () => {
  const session = testClient.startSession()
  session.startTransaction()
  // Store session for rollback
})

afterEach(async () => {
  await session.abortTransaction()
  await session.endSession()
})

Health Checks

typescript
async function checkDatabaseHealth(): Promise<boolean> {
  try {
    await client.db('admin').command({ ping: 1 })
    return true
  } catch {
    return false
  }
}

Didn't find tool you were looking for?

Be as detailed as possible for better results