Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Design MongoDB architectures with document modeling, indexing (ESR rule), sharding, aggregation pipelines, replica sets, and WiredTiger tuning.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | 111% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 410% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 112% | 0% |
| case-04 | ✓→✓ | = Same ✓ | 471% | 0% |
| case-05 | ✓→✓ | = Same ✓ | 1381% | 0% |
Invoke this skill when designing, reviewing, or optimizing MongoDB database architectures for applications requiring flexible schema, document-based data models, horizontal scalability, or high availability.
Trigger Conditions:
Out of Scope:
NOW_ET using NIST/time.gov semantics (America/New_York, ISO-8601).Abort Conditions:
Use Case: Fast path for common scenarios (80% of requests).
Steps:
{status: "active"}).sort({created_at: -1})){age: {$gt: 18}})db.users.createIndex({status: 1, created_at: -1, age: 1})Output: Schema design decision, 3-5 index recommendations with ESR justification, top 3 bottlenecks.
Use Case: Comprehensive architecture for production deployments.
Steps:
Embedding vs Referencing Table:
| Criteria | Embed | Reference | |----------|-------|-----------| | Relationship | 1-to-1, 1-to-many (low cardinality) | many-to-many, 1-to-many (high cardinality) | | Access Pattern | Always queried together | Often queried independently | | Update Frequency | Infrequent updates | Frequent updates to related data | | Data Growth | Bounded, predictable | Unbounded, grows over time | | Document Size | <16 MB total | Risk of exceeding 16 MB limit | | Atomic Writes | Need atomicity across related data | Atomicity not required |
Schema Validation (MongoDB 8.0):
javascriptdb.createCollection("users", { validator: { $jsonSchema: { bsonType: "object", required: ["email", "created_at"], properties: { email: {bsonType: "string", pattern: "^.+@.+$"}, age: {bsonType: "int", minimum: 0, maximum: 150}, created_at: {bsonType: "date"} } } } })
Index Types and Use Cases:
| Index Type | Use Case | Example | |------------|----------|---------| | Single Field | Equality or range on one field | db.users.createIndex({email: 1}) | | Compound (ESR) | Multi-field queries (Equality, Sort, Range) | db.orders.createIndex({status: 1, created_at: -1, total: 1}) | | Multikey | Arrays (e.g., tags, categories) | db.products.createIndex({tags: 1}) | | Text | Full-text search | db.posts.createIndex({content: "text"}) | | Geospatial | Location-based queries (2dsphere) | db.locations.createIndex({coordinates: "2dsphere"}) | | Hashed | Sharding, equality-only queries | db.sessions.createIndex({session_id: "hashed"}) | | Wildcard | Flexible schema with many fields | db.events.createIndex({"metadata.$**": 1}) | | Partial | Index subset of documents | db.users.createIndex({last_login: 1}, {partialFilterExpression: {active: true}}) |
Covered Query Optimization:
javascript// Covered query: all fields in index, no document access db.orders.createIndex({user_id: 1, status: 1, total: 1}) db.orders.find({user_id: 12345, status: "shipped"}, {_id: 0, user_id: 1, status: 1, total: 1}) // explain() shows: totalDocsExamined: 0 (covered by index)
ESR Rule Application:
javascript// Query: Find active users, sort by created_at descending, filter age > 18 db.users.find({status: "active", age: {$gt: 18}}).sort({created_at: -1}) // Correct index (ESR): // Equality: status (exact match) // Sort: created_at (sort field) // Range: age (range filter) db.users.createIndex({status: 1, created_at: -1, age: 1})
Shard Key Selection (MongoDB 8.0):
| Shard Key Type | Use Case | Pros | Cons | |----------------|----------|------|------| | Hashed | Monotonically increasing IDs, even distribution | Uniform write distribution, no hotspots | Cannot use range queries efficiently on shard key | | Ranged | Time-series data, natural ordering | Efficient range queries, targeted reads | Risk of hotspots if monotonic (e.g., timestamp) | | Compound | Multi-tenant apps, complex access patterns | Balances distribution and query targeting | More complex to design |
Hashed Sharding Example:
javascript// Enable sharding on database sh.enableSharding("myapp") // Shard collection with hashed shard key sh.shardCollection("myapp.users", {user_id: "hashed"}) // MongoDB 8.0: Move unsharded collection to specific shard db.adminCommand({moveCollection: "myapp.analytics", toShard: "shard02"})
Ranged Sharding Example (Time-Series):
javascript// Shard by timestamp for time-series data sh.shardCollection("myapp.events", {timestamp: 1}) // Zone sharding (MongoDB 8.0): Route data by date ranges to specific shards sh.addShardToZone("shard01", "recent") sh.updateZoneKeyRange("myapp.events", {timestamp: ISODate("2025-01-01")}, {timestamp: MaxKey}, "recent")
Avoid Scatter-Gather Queries:
db.users.find({user_id: 12345}) → targets single sharddb.users.find({email: "test@example.com"}) → scatter-gather across all shards (slow)Pipeline Stages (Execution Order Matters):
javascript// Optimized aggregation: $match early, $project late, use indexes db.orders.aggregate([ // Stage 1: $match FIRST (uses index, reduces documents) {$match: {status: "shipped", created_at: {$gte: ISODate("2025-01-01")}}}, // Stage 2: $sort (uses index if compound index exists) {$sort: {created_at: -1}}, // Stage 3: $lookup (join with users collection) {$lookup: { from: "users", localField: "user_id", foreignField: "_id", as: "user_details" }}, // Stage 4: $group (aggregation after filtering) {$group: { _id: "$user_id", total_spent: {$sum: "$total"}, order_count: {$sum: 1} }}, // Stage 5: $project LAST (reduce network transfer) {$project: {_id: 1, total_spent: 1, order_count: 1}} ])
Index Sort Optimization:
{status: 1, created_at: -1} index exists, $match + $sort uses index (no in-memory sort).allowDiskUse: true).Sharded Aggregation (MongoDB 8.0):
$match early to enable shard targeting.Standard 3-Member Replica Set:
javascriptrs.initiate({ _id: "myReplicaSet", members: [ {_id: 0, host: "mongo1.example.com:27017", priority: 2}, // Primary (high priority) {_id: 1, host: "mongo2.example.com:27017", priority: 1}, // Secondary {_id: 2, host: "mongo3.example.com:27017", arbiterOnly: true} // Arbiter (no data) ] })
Read Preferences:
primary (default): All reads from primary (strong consistency).primaryPreferred: Read from primary, fallback to secondary if unavailable.secondary: Read from secondary (may read stale data).secondaryPreferred: Read from secondary, fallback to primary.nearest: Read from lowest-latency member.Write Concerns:
w: 1 (default): Acknowledge after primary write (fast, risk of data loss on primary failure).w: "majority": Acknowledge after majority of replica set members (slower, durable).w: 3: Acknowledge after 3 members (explicit count).j: true: Wait for write to journal (disk) before acknowledging.MongoDB 8.0 Replica Set Enhancements:
WiredTiger Cache Sizing (MongoDB 8.0):
yaml# Default: 50% of RAM - 1 GB storage: wiredTiger: engineConfig: cacheSizeGB: 32 # For 64 GB RAM server (50%)
Guidelines:
db.serverStatus().wiredTiger.cache (bytes in cache, eviction activity).Connection Pool Configuration:
javascript// Application connection string mongodb://mongo1.example.com:27017,mongo2.example.com:27017,mongo3.example.com:27017/?replicaSet=myReplicaSet&maxPoolSize=50&minPoolSize=10&maxIdleTimeMS=60000
Settings:
maxPoolSize: Maximum connections (default 100). Each connection ~1 MB RAM.minPoolSize: Minimum connections (default 0). Pre-warm pool for faster queries.maxIdleTimeMS: Close idle connections after timeout (default: no timeout).Configuration Parameters:
yaml# For 64 GB RAM server (OLTP workload) storage: wiredTiger: engineConfig: cacheSizeGB: 32 # 50% of RAM collectionConfig: blockCompressor: snappy # Default compression indexConfig: prefixCompression: true # Index prefix compression net: maxIncomingConnections: 65536 # Max client connections compression: compressors: snappy # Network compression operationProfiling: mode: slowOp # Profile slow queries slowOpThresholdMs: 100 # Log queries >100ms replication: replSetName: myReplicaSet enableMajorityReadConcern: true # Disable for PSA if cache pressure
MongoDB 8.0 Performance Improvements:
Output: Complete architecture document with schema design, index definitions, sharding strategy, aggregation examples, replica set config, tuning parameters.
Use Case: Multi-region deployments, queryable encryption, sharding at scale, version migrations.
Steps:
javascriptrs.initiate({ _id: "globalReplicaSet", members: [ {_id: 0, host: "us-east-1.example.com:27017", priority: 2, tags: {region: "us-east"}}, {_id: 1, host: "us-east-2.example.com:27017", priority: 1, tags: {region: "us-east"}}, {_id: 2, host: "eu-west-1.example.com:27017", priority: 1, tags: {region: "eu-west"}}, {_id: 3, host: "ap-southeast-1.example.com:27017", priority: 1, tags: {region: "ap-southeast"}}, {_id: 4, host: "arbiter.example.com:27017", arbiterOnly: true} ], settings: { // Read from nearest region getLastErrorDefaults: {w: "majority", wtimeout: 5000} } }) // Region-specific read preferences db.users.find({region: "us-east"}).readPref("nearest", [{region: "us-east"}])
Use Case: Encrypt sensitive fields (PII, PHI) while allowing queries.
javascript// Create encrypted collection (MongoDB 8.0 expanded support) db.createCollection("patients", { encryptedFields: { fields: [ { path: "ssn", bsonType: "string", queries: {queryType: "equality"} // Allow equality queries on encrypted field }, { path: "medical_record", bsonType: "string" // No queries specification = cannot query, only store/retrieve } ] } }) // Query encrypted field db.patients.find({ssn: "123-45-6789"}) // Allowed (queryable encryption)
Parallel Execution on Sharded Cluster:
javascript// Aggregation runs in parallel on each shard, then merges db.orders.aggregate([ {$match: {created_at: {$gte: ISODate("2025-01-01")}}}, // Shard targeting if sharded by created_at {$group: {_id: "$product_id", total_sales: {$sum: "$total"}}}, {$sort: {total_sales: -1}}, {$limit: 10} ], {allowDiskUse: true}) // Allow >100 MB sort for large datasets
Optimization:
$match with date range targets recent shards only.db.currentOp() to see query distribution across shards.Benefits of MongoDB 8.0:
Migration Strategy (Zero-Downtime):
rs.stepDown()) → elect MongoDB 8.0 member as new primary.db.adminCommand({setFeatureCompatibilityVersion: "8.0"}).Risks:
Key Metrics:
javascript// Server status db.serverStatus() // WiredTiger cache stats db.serverStatus().wiredTiger.cache // Monitor: bytes currently in cache, bytes read into cache, eviction activity // Connection stats db.serverStatus().connections // Monitor: current, available, totalCreated // Operation counters db.serverStatus().opcounters // Monitor: insert, query, update, delete, getmore, command // Slow query profiling db.system.profile.find({millis: {$gt: 100}}).sort({ts: -1}).limit(10) // Index usage stats db.collection.aggregate([{$indexStats: {}}])
Tools:
Output: Multi-region architecture, queryable encryption setup, cross-shard aggregation strategy, migration plan with risks, monitoring dashboards.
w: "majority" for critical writes (durability over speed).readPreference: "secondary" for analytics queries (offload primary).$match as early as possible (reduce documents).$match and $sort stages.$project last to reduce network transfer.allowDiskUse: true for >100 MB sorts/groups.Uncertainty Thresholds:
Required Fields:
yamldocument_schema: - collection_name: string embedding_decision: "embed" | "reference" justification: string (why embed or reference) schema_validation: object (JSON schema) sample_document: object indexes: - collection_name: string index_name: string index_definition: object ({field: 1|-1}) index_type: "single" | "compound" | "multikey" | "text" | "geospatial" | "hashed" | "wildcard" | "partial" esr_justification: string (if compound index) estimated_speedup: string (e.g., "50x faster") sharding_strategy: - enabled: boolean shard_key: object ({field: "hashed" | 1}) shard_key_type: "hashed" | "ranged" | "compound" justification: string (why this shard key) target_chunk_size: string (default: "64 MB") aggregation_examples: - use_case: string pipeline: array (aggregation stages) optimization_notes: string replica_set: - members: integer (3, 5, etc.) configuration: object (rs.initiate() config) read_preference: "primary" | "primaryPreferred" | "secondary" | "secondaryPreferred" | "nearest" write_concern: object ({w: "majority", j: true}) performance_tuning: - wiredtiger_cache_gb: number max_connections: integer connection_pool_size: integer profiling_threshold_ms: integer estimated_improvement: string (e.g., "36% faster reads") migration_plan: # If upgrading versions - current_version: string target_version: string strategy: "rolling upgrade" | "blue-green" | "snapshot restore" steps: array (migration steps) risks: array (potential issues) downtime_estimate: string
Token Tier Minimums:
ESR Rule for Compound Index:
javascript// Query: Find active users, sort by created_at descending, filter age > 18 db.users.find({status: "active", age: {$gt: 18}}).sort({created_at: -1}) // Index following ESR rule: // E (Equality): status // S (Sort): created_at // R (Range): age db.users.createIndex({status: 1, created_at: -1, age: 1})
See examples/content-management-mongodb-architecture.txt for a complete architecture example.
Official MongoDB Documentation:
Performance & Best Practices:
Tools:
Other measured skills in the registry, with their headline benchmark lift.