MongoDB Core Knowledge
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: mongodb for comprehensive documentation.
CRUD Operations
// Create db.users.insertOne({ name: "John", email: "john@example.com", createdAt: new Date() });
// Read db.users.find({ isActive: true }) .sort({ createdAt: -1 }) .limit(20);
db.users.findOne({ _id: ObjectId("...") });
// Update db.users.updateOne( { _id: ObjectId("...") }, { $set: { name: "Jane" } } );
// Delete db.users.deleteOne({ _id: ObjectId("...") });
Query Operators
// Comparison { age: { $gt: 18, $lt: 65 } } { status: { $in: ["active", "pending"] } }
// Logical { $and: [{ age: { $gt: 18 } }, { isActive: true }] } { $or: [{ status: "admin" }, { role: "moderator" }] }
// Array { tags: { $all: ["tech", "news"] } } { "scores.0": { $gt: 90 } }
Aggregation Pipeline
db.orders.aggregate([ { $match: { status: "completed" } }, { $group: { _id: "$userId", totalSpent: { $sum: "$amount" }, orderCount: { $count: {} } }}, { $sort: { totalSpent: -1 } }, { $limit: 10 } ]);
Indexes
db.users.createIndex({ email: 1 }, { unique: true }); db.users.createIndex({ createdAt: -1 }); db.users.createIndex({ name: "text" }); // Text search
Production Readiness
Security Configuration
// Enable authentication (mongod.conf) // security: // authorization: enabled
// Create admin user use admin db.createUser({ user: "admin", pwd: "secure_password", roles: ["root"] });
// Create application user with limited privileges use mydb db.createUser({ user: "app_user", pwd: "app_password", roles: [ { role: "readWrite", db: "mydb" } ] });
// Create read-only user for reporting db.createUser({ user: "reporter", pwd: "reporter_password", roles: [{ role: "read", db: "mydb" }] });
mongod.conf - Security settings
security: authorization: enabled
net: ssl: mode: requireSSL PEMKeyFile: /path/to/mongodb.pem CAFile: /path/to/ca.pem
Connection with SSL
// Node.js connection with SSL const { MongoClient } = require('mongodb');
const client = new MongoClient('mongodb://host:27017', { ssl: true, sslCA: fs.readFileSync('/path/to/ca.pem'), sslCert: fs.readFileSync('/path/to/client.pem'), sslKey: fs.readFileSync('/path/to/client.key'), authSource: 'admin', });
Replica Set (High Availability)
// Initialize replica set rs.initiate({ _id: "myReplicaSet", members: [ { _id: 0, host: "mongo1:27017", priority: 2 }, { _id: 1, host: "mongo2:27017", priority: 1 }, { _id: 2, host: "mongo3:27017", priority: 1 } ] });
// Connection string for replica set mongodb://mongo1:27017,mongo2:27017,mongo3:27017/mydb?replicaSet=myReplicaSet&readPreference=secondaryPreferred
Backup & Recovery
mongodump backup
mongodump --uri="mongodb://user:pass@host:27017/mydb"
--out=/backup/$(date +%Y%m%d)
--gzip
mongorestore
mongorestore --uri="mongodb://user:pass@host:27017/mydb"
--gzip /backup/20240115
Continuous backup with oplog
mongodump --oplog --out=/backup/full
Point-in-time recovery
mongorestore --oplogReplay --oplogLimit=1705315200 /backup/full
Performance Tuning
// Index best practices db.collection.createIndex({ field: 1 }, { background: true });
// Compound indexes for common queries db.orders.createIndex({ userId: 1, createdAt: -1 });
// TTL index for automatic expiration db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 });
// Partial indexes for filtered queries db.orders.createIndex( { status: 1 }, { partialFilterExpression: { status: { $in: ["pending", "processing"] } } } );
// Analyze query performance db.orders.find({ userId: "123" }).explain("executionStats");
Monitoring Metrics
Metric Alert Threshold
Connection count
80% max
Replication lag
10 seconds
Query targeting
1000 docs examined/returned
Cache hit ratio < 95%
Oplog window < 24 hours
Disk usage
80%
Monitoring Commands
// Server status db.serverStatus();
// Current operations db.currentOp({ "active": true, "secs_running": { "$gt": 5 } });
// Replication status rs.status();
// Index usage stats db.collection.aggregate([{ $indexStats: {} }]);
// Collection stats db.collection.stats();
// Database profiler (slow queries) db.setProfilingLevel(1, { slowms: 100 }); db.system.profile.find().sort({ ts: -1 }).limit(10);
Read/Write Concerns
// Write concern for durability db.orders.insertOne(order, { writeConcern: { w: "majority", j: true, wtimeout: 5000 } });
// Read concern for consistency db.orders.find({ userId: "123" }).readConcern("majority");
// Read preference for scaling reads db.orders.find().readPref("secondaryPreferred");
Sharding (Horizontal Scaling)
// Enable sharding on database sh.enableSharding("mydb");
// Shard collection with hashed key sh.shardCollection("mydb.orders", { _id: "hashed" });
// Shard collection with range key sh.shardCollection("mydb.logs", { timestamp: 1 });
// Check sharding status sh.status();
Checklist
-
Authentication enabled
-
TLS/SSL encryption enabled
-
Least-privilege user accounts
-
Replica set configured (3+ nodes)
-
Regular mongodump backups
-
Oplog size adequate for recovery window
-
Indexes on query fields
-
Query profiler enabled (slow queries)
-
Write concern: majority + journal
-
Connection pooling configured
-
Monitoring alerts configured
-
Sharding (if > 100GB or high throughput)
When NOT to Use This Skill
-
Relational data with complex joins - Use postgresql or mysql for relational databases
-
Transactions across multiple tables - Use SQL databases with ACID guarantees
-
Full-text search - Use elasticsearch for advanced search features
-
Caching - Use redis for in-memory caching
-
Graph relationships - Consider Neo4j or graph databases
Anti-Patterns
Anti-Pattern Issue Solution
Unbounded array growth Document size limit (16MB), performance degradation Use separate collection or capped arrays
Missing indexes on queries Collection scans, slow performance Create indexes on query fields
Using $lookup excessively Poor performance, not optimized for joins Denormalize data or redesign schema
Storing large binary data Exceeds 16MB limit, slow queries Use GridFS for files > 16MB
Not using projection Transfers unnecessary data Specify needed fields in projection
Ignoring write concern Data loss risk Use majority write concern for important data
Not using read preference Overloading primary Use secondary reads for analytics
Massive embedded documents Hard to query, update complexity Split into separate collections
Not handling connection pooling Connection exhaustion Configure proper pool size
Using count() on large collections Slow, scans collection Use countDocuments() or estimatedDocumentCount()
Quick Troubleshooting
Problem Diagnostic Fix
Slow queries db.collection.explain("executionStats")
Add indexes, check query pattern
High memory usage db.serverStatus().mem
Increase RAM, optimize indexes
Connection pool exhausted Check connection count Increase pool size, fix connection leaks
Replication lag rs.status() and check optimeDate
Increase resources, tune oplog size
Disk space full db.stats()
Compact collections, increase storage
Index not being used explain() shows COLLSCAN Verify index exists, check query shape
Write conflicts Check error logs for writeConflict Retry logic, reduce concurrent updates
Document too large Error: "document is larger than 16MB" Use GridFS or split document
Reference Documentation
-
Aggregation
-
Indexes