mongodb
Administer MongoDB databases. Configure replica sets, sharding, and backups. Use when managing MongoDB deployments.
Works with
---
name: mongodb
description: Administer MongoDB databases. Configure replica sets, sharding, and backups. Use when managing MongoDB deployments.
license: MIT
---
# MongoDB
Administer, optimize, and secure MongoDB NoSQL databases in development and production environments.
## When to Use
- You need a document-oriented database with flexible schemas.
- Your data is semi-structured or heavily nested (JSON-like documents).
- You need horizontal scaling through sharding.
- Your application benefits from rich querying and aggregation pipelines.
## Prerequisites
- Linux server (Debian/Ubuntu or RHEL-based) or Docker.
- Root or sudo access for package installation.
- MongoDB 7.x recommended for production (6.x still supported).
## Installation and Setup
```bash
# Debian / Ubuntu — MongoDB 7
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
sudo apt update
sudo apt install -y mongodb-org
# Start and enable
sudo systemctl enable --now mongod
# Verify
mongosh --eval "db.version()"
```
## Initial User Setup
```javascript
// Connect without auth first
// mongosh
use admin
// Create admin user
db.createUser({
user: "admin",
pwd: "strong_admin_password",
roles: [
{ role: "userAdminAnyDatabase", db: "admin" },
{ role: "readWriteAnyDatabase", db: "admin" },
{ role: "clusterAdmin", db: "admin" }
]
})
// Create an application-scoped user
use mydb
db.createUser({
user: "myapp",
pwd: "strong_app_password",
roles: [{ role: "readWrite", db: "mydb" }]
})
```
Enable authentication in `/etc/mongod.conf`:
```yaml
security:
authorization: enabled
```
```bash
sudo systemctl restart mongod
# Now connect with credentials
mongosh -u myapp -p strong_app_password --authenticationDatabase mydb
```
## mongosh Commands Reference
```javascript
// Show databases and collections
show dbs
use mydb
show collections
// Insert documents
db.users.insertOne({ name: "Alice", email: "alice@example.com", age: 30 })
db.users.insertMany([
{ name: "Bob", email: "bob@example.com", age: 25 },
{ name: "Carol", email: "carol@example.com", age: 35 }
])
// Query documents
db.users.find({ age: { $gte: 25 } }).sort({ name: 1 }).limit(10)
db.users.findOne({ email: "alice@example.com" })
db.users.countDocuments({ age: { $gte: 30 } })
// Update
db.users.updateOne(
{ email: "alice@example.com" },
{ $set: { age: 31 }, $currentDate: { updatedAt: true } }
)
db.users.updateMany(
{ age: { $lt: 30 } },
{ $set: { tier: "junior" } }
)
// Delete
db.users.deleteOne({ email: "bob@example.com" })
db.users.deleteMany({ tier: "junior" })
```
## Indexing
```javascript
// Single-field index
db.users.createIndex({ email: 1 }, { unique: true })
// Compound index
db.orders.createIndex({ userId: 1, createdAt: -1 })
// Text index for search
db.articles.createIndex({ title: "text", body: "text" })
db.articles.find({ $text: { $search: "mongodb scaling" } })
// TTL index — auto-delete documents after 30 days
db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 2592000 })
// List indexes
db.users.getIndexes()
// Drop an index
db.users.dropIndex("email_1")
// Explain a query to verify index usage
db.orders.find({ userId: 42 }).explain("executionStats")
```
## Aggregation Pipeline Examples
```javascript
// Revenue per status
db.orders.aggregate([
{ $group: {
_id: "$status",
totalRevenue: { $sum: "$total" },
count: { $sum: 1 }
}},
{ $sort: { totalRevenue: -1 } }
])
// Top 5 customers by order value (with a join)
db.orders.aggregate([
{ $group: {
_id: "$userId",
spent: { $sum: "$total" },
orderCount: { $sum: 1 }
}},
{ $sort: { spent: -1 } },
{ $limit: 5 },
{ $lookup: {
from: "users",
localField: "_id",
foreignField: "_id",
as: "user"
}},
{ $unwind: "$user" },
{ $project: {
_id: 0,
name: "$user.name",
email: "$user.email",
spent: 1,
orderCount: 1
}}
])
// Daily signup trend
db.users.aggregate([
{ $group: {
_id: { $dateToString: { format: "%Y-%m-%d", date: "$createdAt" } },
signups: { $sum: 1 }
}},
{ $sort: { _id: 1 } },
{ $limit: 30 }
])
```
## Replica Set Setup
A replica set requires a minimum of three members (or two data-bearing nodes plus an arbiter).
### Configuration File for Each Member
```yaml
# /etc/mongod.conf (adjust port and dbPath per member)
storage:
dbPath: /var/lib/mongodb
net:
port: 27017
bindIp: 0.0.0.0
replication:
replSetName: rs0
security:
authorization: enabled
keyFile: /etc/mongodb-keyfile
```
```bash
# Generate a shared keyfile for internal auth
openssl rand -base64 756 > /etc/mongodb-keyfile
chmod 400 /etc/mongodb-keyfile
chown mongodb:mongodb /etc/mongodb-keyfile
# Copy this file to all replica set members
```
### Initialize the Replica Set
```javascript
// Connect to the first member
// mongosh --port 27017
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1 }
]
})
// Check status
rs.status()
// View replication lag per member
rs.printReplicationInfo()
rs.printSecondaryReplicationInfo()
```
## Backup and Restore
```bash
# Full dump of all databases
mongodump --uri="mongodb://admin:secret@localhost:27017" --out=/backups/full_$(date +%F)
# Single database
mongodump --uri="mongodb://myapp:secret@localhost:27017/mydb" --out=/backups/mydb_$(date +%F)
# Compressed dump
mongodump --uri="mongodb://admin:secret@localhost:27017" --gzip --out=/backups/gz_$(date +%F)
# Restore all databases
mongorestore --uri="mongodb://admin:secret@localhost:27017" /backups/full_2025-01-15/
# Restore a single database, dropping existing data first
mongorestore --uri="mongodb://admin:secret@localhost:27017" \
--drop --db mydb /backups/mydb_2025-01-15/mydb/
# Restore compressed dump
mongorestore --uri="mongodb://admin:secret@localhost:27017" --gzip /backups/gz_2025-01-15/
```
## Docker Compose Setup
```yaml
# docker-compose.yml
version: "3.9"
services:
mongo1:
image: mongo:7
restart: unless-stopped
ports:
- "27017:27017"
environment:
MONGO_INITDB_ROOT_USERNAME: admin
MONGO_INITDB_ROOT_PASSWORD: secret
volumes:
- mongo1_data:/data/db
- ./mongo-keyfile:/etc/mongodb-keyfile:ro
command: >
mongod
--replSet rs0
--keyFile /etc/mongodb-keyfile
--bind_ip_all
healthcheck:
test: ["CMD", "mongosh", "--eval", "db.adminCommand('ping')"]
interval: 10s
timeout: 5s
retries: 5
mongo2:
image: mongo:7
restart: unless-stopped
volumes:
- mongo2_data:/data/db
- ./mongo-keyfile:/etc/mongodb-keyfile:ro
command: >
mongod
--replSet rs0
--keyFile /etc/mongodb-keyfile
--bind_ip_all
mongo3:
image: mongo:7
restart: unless-stopped
volumes:
- mongo3_data:/data/db
- ./mongo-keyfile:/etc/mongodb-keyfile:ro
command: >
mongod
--replSet rs0
--keyFile /etc/mongodb-keyfile
--bind_ip_all
mongo-init:
image: mongo:7
restart: "no"
depends_on:
mongo1:
condition: service_healthy
entrypoint: >
mongosh --host mongo1 -u admin -p secret --authenticationDatabase admin --eval '
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017", priority: 2 },
{ _id: 1, host: "mongo2:27017", priority: 1 },
{ _id: 2, host: "mongo3:27017", priority: 1 }
]
})
'
volumes:
mongo1_data:
mongo2_data:
mongo3_data:
```
```bash
# Generate keyfile before starting
openssl rand -base64 756 > mongo-keyfile
chmod 400 mongo-keyfile
docker compose up -d
# Connect
mongosh "mongodb://admin:secret@127.0.0.1:27017/?replicaSet=rs0&authSource=admin"
```
## Monitoring Queries
```javascript
// Server status summary
db.serverStatus().connections
db.serverStatus().opcounters
// Current operations (look for long-running queries)
db.currentOp({ secs_running: { $gte: 5 } })
// Collection stats
db.orders.stats()
// Index sizes
db.orders.stats().indexSizes
// Profiler — log slow queries (> 100ms)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(5)
// Replica set lag
rs.printSecondaryReplicationInfo()
```
## Configuration Tuning
```yaml
# /etc/mongod.conf — production recommendations
storage:
dbPath: /var/lib/mongodb
journal:
enabled: true
wiredTiger:
engineConfig:
cacheSizeGB: 4 # ~50% of RAM, leave rest for OS cache
collectionConfig:
blockCompressor: snappy
net:
port: 27017
bindIp: 0.0.0.0
maxIncomingConnections: 500
operationProfiling:
mode: slowOp
slowOpThresholdMs: 100
```
## Troubleshooting
| Symptom | Likely Cause | Fix |
|---|---|---|
| `COLLSCAN` in explain output | Missing index on queried field | Create an appropriate index |
| Replica member stuck in `RECOVERING` | Oplog window exceeded | Resync by removing data and restarting the member |
| `too many open files` | OS file descriptor limit too low | Set `ulimit -n 65535` in service file |
| High memory usage | WiredTiger cache too large | Reduce `cacheSizeGB` in config |
| Slow aggregation pipelines | No index on `$match` stage fields | Add index; place `$match` as early as possible in pipeline |
| Authentication failure | Wrong `authenticationDatabase` | Specify `--authenticationDatabase admin` for admin users |
## Related Skills
- [redis](../redis/) - Caching layer in front of MongoDB
- [database-backups](../database-backups/) - Automated backup strategies
- [postgresql](../postgresql/) - Alternative relational databaseMore Database skills
supabase-postgres-best-practices
supabase/agent-skills
Postgres best practices maintained by Supabase, for Postgres running anywhere. Load this skill BEFORE writing or changing anything that lives in a Postgres database: creating or altering tables and columns (including choosing column types), schema design, migrations and declarative schema files, RLS policies and the tests that verify them, indexes, triggers, database functions, queues and scheduled jobs (pg_cron, pgmq), vector/semantic search (pgvector), and restoring dumps (pg_restore) or importing data. Also load it when diagnosing slow queries, high CPU, timeouts, EXPLAIN plans, connection exhaustion, locking, bloat, or rows visible to the wrong user or tenant. This is not just a performance guide — schema, migration, security, and SQL authoring tasks need these rules too, even for a one-column change or a single query.
prisma-database-setup
prisma/skills
Guides for configuring Prisma with different database providers (PostgreSQL, MySQL, SQLite, MongoDB, etc.). Use when setting up a new project, changing databases, or troubleshooting connection issues. Triggers on "configure postgres", "connect to mysql", "setup mongodb", "sqlite setup".
prisma-postgres
prisma/skills
Prisma Postgres setup and operations guidance across Console, create-db CLI, Management API, and Management API SDK. Use when creating Prisma Postgres databases, working in Prisma Console, provisioning with create-db/create-pg/create-postgres, or integrating programmatic provisioning with service tokens or OAuth.

