MongoDB — schema design, indexes, aggregation, sharding, Atlas.
Scanned 9/5/2026
Install to Claude Code
npx -y skills add Dev-Toolbelt/dev-team-agents --skill mongodb --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Mongodb?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/dev-toolbelt-mongodb)More formats (shields.io, HTML) on the badges page.
---
name: mongodb
description: MongoDB — schema design, indexes, aggregation, sharding, Atlas.
---
# MongoDB Reference
## When to Load
Load when the project uses MongoDB (signal: `mongoose`, `mongodb`, `mongo:` in docker-compose, `MONGODB_URI`).
## CLI Connection
```bash
mongosh "$MONGO_URI"
# or with individual vars:
mongosh "mongodb://$DB_USER:$DB_PASSWORD@$DB_HOST:${DB_PORT:-27017}/$DB_NAME"
# Atlas:
mongosh "mongodb+srv://$DB_USER:$DB_PASSWORD@$ATLAS_CLUSTER/$DB_NAME"
```
Key inspection commands:
```js
db.stats() // database size and counts
db.collection.stats() // collection storage details
db.collection.explain("executionStats").find({...}) // query plan
db.currentOp({ active: true }) // running operations
db.collection.getIndexes() // list all indexes
```
## Schema Design Principles
| Decision | Embed | Reference |
|----------|-------|-----------|
| Data is always accessed together | yes | — |
| Data grows unboundedly (comments on a post) | — | yes |
| Data is shared across many documents | — | yes |
| Max document size | — | 16 MB limit; embed only bounded sub-arrays |
**Rule of thumb**: embed for one-to-few; reference for one-to-many or many-to-many.
## Indexes
| Type | Use when |
|------|----------|
| Single-field | Filter or sort on one field |
| Compound | Multi-field queries; field order matches query selectivity |
| Multikey | Index array values; MongoDB creates one entry per array element |
| Text | Full-text search (`$text`); use Atlas Search for production |
| 2dsphere | Geospatial queries (`$near`, `$geoWithin`) |
| Partial | `partialFilterExpression` to index a subset of documents |
| Sparse | Skip documents where the field is absent |
| TTL | Auto-delete documents after a duration: `expireAfterSeconds` |
Always run `explain("executionStats")` to verify `IXSCAN` (not `COLLSCAN`).
## Aggregation Pipeline
Prefer aggregation over MapReduce (deprecated in 5.0+):
- `$match` → `$group` → `$sort` → `$limit` (always filter early, sort late)
- `$lookup` for joins (use only for occasional aggregations; not for hot paths)
- `$unwind` before `$group` when working with arrays
- `allowDiskUse: true` for large aggregations that exceed 100 MB memory limit
## Write Concerns & Read Preferences
| Concern | Guarantee |
|---------|-----------|
| `w: 1` (default) | Acknowledged by primary |
| `w: "majority"` | Acknowledged by majority of replica set members |
| `j: true` | Written to journal before acknowledgement |
For financial or critical data: use `w: "majority", j: true`.
Read preferences: `primary` (default, strong consistency), `primaryPreferred`, `secondary` (eventual consistency, lower load on primary).
## Sharding
- Shard key choice is critical and cannot be changed after collection creation
- Good shard key: high cardinality, even distribution, frequently in queries
- Bad shard key: low cardinality (e.g., boolean), monotonically increasing (e.g., timestamp → hotspot)
- Use hashed shard key for even distribution when range queries are rare
## Transactions
Available since MongoDB 4.0 (replica sets) and 4.2 (sharded clusters):
- Use sparingly; multi-document transactions have performance overhead
- Keep transactions short; avoid user interactions inside a transaction
- Prefer single-document atomic operations where possible
## Atlas-Specific
| Feature | Use when |
|---------|----------|
| Atlas Search | Full-text, fuzzy, autocomplete (Lucene-backed) |
| Atlas Triggers | React to DB events without polling |
| Atlas Data API | HTTP access without MongoDB driver |
| Online Archive | Auto-tier cold data to S3 |
## Common Gotchas
| Gotcha | Fix |
|--------|-----|
| `findOne` returns `null` not an exception | Always check for null before accessing fields |
| `_id` is an ObjectId, not a string | Serialize with `.toString()`; never compare `==` to a string |
| Unbounded array growth | Use `$push` with `$slice` or move to a separate collection |
| Schema-less does not mean schema-free | Use Mongoose validators or JSON Schema validation |
| Large `$in` arrays cause slow index scans | Cap `$in` lists; consider `$lookup` + `$match` |
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!