## Introduction

MongoDB administrators and developers often need to inspect databases, diagnose issues, and verify changes without disrupting production traffic. This guide provides a practical command reference for daily MongoDB operations, covering version identification, environment inventory, safe configuration, diagnostics, failure recovery, and an operations checklist.

Every command includes prerequisites, expected output, potential failure signals, and recovery guidance. The focus is operational safety: always observe before changing, limit the blast radius, use placeholders instead of real credentials, and verify results before moving on.

This guide is written for MongoDB 6.0 and later, using the mongosh shell. Commands are tested against standalone instances and replica sets. Sharded cluster considerations are noted where relevant.

## 1. Version and Environment Inventory

Before running any command, identify the installed MongoDB version, edition, and deployment topology. This prevents using unsupported syntax or applying changes meant for a different architecture.

### 1.1 Check Server Version and Build Info

Run the following inside mongosh to get detailed server information:

// Connect to the target instance
mongosh "mongodb://localhost:27017" --username admin --password 'YOUR_PASSWORD' --authenticationDatabase admin

// Get server build info
db.version()
// Expected output example: '6.0.5'

db.runCommand({ buildInfo: 1 }) 
 The buildInfo command returns a document with fields like version , gitVersion , modules , allocator , and maxBsonObjectSize . Example output:

{
 "version": "6.0.5",
 "gitVersion": "abc123...",
 "modules": [],
 "allocator": "tcmalloc",
 "maxBsonObjectSize": 16777216,
 "ok": 1
} 
 Why this matters : Different MongoDB versions support different features and command options. For example, the $merge aggregation stage was introduced in 4.2, and updateOne with pipeline updates requires 4.2+. Knowing the exact version prevents syntax errors.

Failure signal : If db.version() returns an error or a version string that is not a valid MongoDB version, check the connection string and authentication. Ensure the mongosh binary corresponds to a compatible version.

### 1.2 Determine Deployment Topology

Use rs.status() to check if the instance is part of a replica set:

rs.status().set // Returns the replica set name if configured 
 If the command throws an error like not running with --replSet , the instance is standalone. For a sharded cluster, connect to a mongos router and run:

sh.status() 
 This shows shards, chunks distribution, and balancer status.

Use case : On a replica set, you can safely perform maintenance on a secondary by first running rs.stepDown() on the primary. On a standalone, you must schedule downtime for certain operations.

### 1.3 Read-Only Observation of Current State

Capture current databases, collections, and key metrics without making changes:

show dbs // List databases and sizes
use targetDatabase // Switch context
show collections // List collections in current db
db.stats() // Collection-level stats (size, count, indexes) 
 Example output for show dbs :

admin 0.000GB
config 0.000GB
local 0.000GB
mydb 0.001GB 
 Always record the output and timestamp before making any changes. This provides a rollback reference.

## 2. Safe Configuration Path

Configuration changes in MongoDB are typically made via setParameter or by modifying the configuration file. Follow a strict process: observe current settings, make one scoped change, verify, and know how to revert.

### 2.1 View Current Configuration Parameters

db.adminCommand({ getParameter: '*' }) 
 This returns a large document with all runtime parameters. To filter for a specific parameter, for example logLevel :

db.adminCommand({ getParameter: 1, logLevel: 1 }) 

### 2.2 Change a Parameter Safely

 Example: Increase the log verbosity to diagnose a slow query, but only temporarily.

// Before: logLevel is 0 (default)
// Set logLevel to 1 (more verbose)
db.adminCommand({ setParameter: 1, logLevel: 1 })
// Expected: { "was": 0, "ok": 1 }

// After diagnosis, revert to 0
db.adminCommand({ setParameter: 1, logLevel: 0 }) 
 Blast radius : The setParameter command affects the entire instance and persists only until restart unless set in the config file. For production, always test in staging first.

Verification : Re-run the getParameter command to confirm the new value is applied.

Recovery : If the change causes performance issues, set the parameter back to its original value. If the instance becomes unresponsive, restart the mongod process, and the runtime parameter reverts to the config file value (or default).

### 2.3 Configuration File Changes

For permanent changes, edit the mongod.conf file (typically /etc/mongod.conf on Linux). After editing, restart the mongod service:

sudo systemctl restart mongod 
 Always back up the original config file before editing:

cp /etc/mongod.conf /etc/mongod.conf.bak 
 After restart, verify the new setting is active:

db.adminCommand({ getParameter: 1, <parameterName>: 1 }) 

## 3. Core CRUD Commands with Examples

 CRUD operations form the backbone of daily administration and development. Below are practical examples with expected outputs.

### 3.1 Create a Database and Collection

MongoDB creates databases and collections implicitly on first insert.

use sales // Switch to 'sales' db (not yet created)
db.orders.insertOne({
 _id: ObjectId(),
 customer: "Acme Corp",
 items: [
 { sku: "ABC123", qty: 2, price: 10.99 },
 { sku: "XYZ789", qty: 1, price: 24.50 }
 ],
 status: "pending",
 createdAt: new Date()
})
// Expected: { acknowledged: true, insertedId: ObjectId("...") } 
 Now sales and orders exist.

### 3.2 Read Documents

db.orders.find({ status: "pending" }).pretty() 
 Count documents:

db.orders.countDocuments({ status: "pending" }) 
 Find one by _id :

db.orders.findOne({ _id: ObjectId("60f7b1c2e4b0a1c2e4b0a1c2") }) 

### 3.3 Update Documents

 Update one field:

db.orders.updateOne(
 { _id: ObjectId("60f7b1c2e4b0a1c2e4b0a1c2") },
 { $set: { status: "shipped" } }
)
// Expected: { acknowledged: true, matchedCount: 1, modifiedCount: 1 } 
 Update with an aggregation pipeline (version 4.2+):

db.orders.updateOne(
 { _id: ObjectId("60f7b1c2e4b0a1c2e4b0a1c2") },
 [ { $set: { itemCount: { $size: "$items" } } } ]
) 

### 3.4 Delete Documents

 Delete one:

db.orders.deleteOne({ _id: ObjectId("60f7b1c2e4b0a1c2e4b0a1c2") })
// Expected: { acknowledged: true, deletedCount: 1 } 
 Delete many based on condition:

db.orders.deleteMany({ status: "cancelled" })
// Expected: { acknowledged: true, deletedCount: 3 } // example number 
 Pitfall : Accidentally omitting the filter in deleteMany({}) deletes all documents. Always use filters or consider using deleteOne for targeted deletes. To protect against accidental mass deletion, enable the --setParameter protectAuditedDeletes=true option (available from MongoDB 5.0 for replica sets).

## 4. Indexing and Performance

Proper indexing is critical for query performance. Here are commands to manage indexes safely.

### 4.1 View Existing Indexes

db.orders.getIndexes() 
 Expected output:

[
 { "v": 2, "key": { "_id": 1 }, "name": "_id_" },
 { "v": 2, "key": { "status": 1 }, "name": "status_1" }
] 

### 4.2 Create an Index

 Create a single-field index:

db.orders.createIndex({ customer: 1 })
// Expected: { numIndexesBefore: 2, numIndexesAfter: 3, createdCollectionAutomatically: false, ok: 1 } 
 Create a compound index:

db.orders.createIndex({ status: 1, createdAt: -1 }) 
 Create a unique index:

db.orders.createIndex({ orderNumber: 1 }, { unique: true }) 
 Blast radius : Index creation on a large collection can lock the database in older versions but uses a hybrid build in MongoDB 4.2+ that minimizes impact. Monitor with currentOp() during creation.

Verification : Use db.orders.getIndexes() to confirm the index appears. Use explain() to verify the index is used:

db.orders.find({ customer: "Acme Corp" }).explain("executionStats") 
 Check winningPlan.inputStage.indexName to see if the index is chosen.

### 4.3 Drop an Index

Only drop indexes that are not used. To identify unused indexes, query the $indexStats aggregation (available from MongoDB 4.2):

db.orders.aggregate([ { $indexStats: {} } ]) 
 Look for indexes with zero accesses. Drop with:

db.orders.dropIndex("customer_1") 
 Recovery : If performance degrades after dropping, recreate the index. Keeping a script with index definitions is recommended.

## 5. Verification and Diagnostics

Diagnostic commands help identify slow operations, resource contention, and replication lag.

### 5.1 Check Current Operations

db.currentOp() 
 Filter for active operations longer than 10 seconds:

db.currentOp({ "active": true, "secs_running": { $gt: 10 } }) 
 Expected output : A document array with opid , op , ns , secs_running , query , and client . Identify long-running operations and kill them if necessary.

Kill an operation by opid :

db.killOp(123456) 
 Caution : Killing an operation can cause rollback; use only on clearly stuck operations.

### 5.2 Replication Lag and Status

On a replica set, check status:

rs.status() 
 Examine members array for each member's stateStr (PRIMARY, SECONDARY, etc.) and pingMs . Compute replication lag:

rs.printSecondaryReplicationInfo() 
 Example output:

source: mongo1:27017
 syncedTo: Sun Jan 07 2024 10:15:30 GMT+0000 (UTC)
 0 secs (0 hrs) behind the primary 
 Failure signal : If lag exceeds a threshold (e.g., 10 seconds for high-write systems), investigate network issues, secondary hardware, or long-running transactions on the primary.

### 5.3 Server Status Metrics

db.serverStatus() 
 Key metrics to watch:

- connections.current and connections.available

- opcounters for read/write rates

- mem.resident for memory usage

- locks for contention

- wiredTiger.cache for cache eviction pressure

Use a monitoring tool or script to collect these over time.

## 6. Backup and Restore Essentials

Backups are non-negotiable. Use mongodump and mongorestore for logical backups.

### 6.1 Create a Logical Backup

mongodump --uri="mongodb://admin:YOUR_PASSWORD@localhost:27017" --out=/backup/$(date +%Y%m%d) 
 This creates BSON files for each collection in the specified output directory. For a single database:

mongodump --db sales --out=/backup/sales_$(date +%Y%m%d) 
 Verification : After backup, check the output directory and file sizes. Optionally, restore to a staging instance to test backup integrity.

### 6.2 Restore from Backup

mongorestore --uri="mongodb://admin:YOUR_PASSWORD@localhost:27017" /backup/20240107/sales 
 Important : mongorestore does not drop existing data by default; it merges. To replace a database, use --drop :

mongorestore --drop --db sales /backup/20240107/sales 
 Failure and recovery : If restore fails due to index build issues, use --noIndexRestore and rebuild indexes after. Always test restores periodically.

### 6.3 Filesystem Snapshots

For large databases, filesystem snapshots (e.g., LVM, AWS EBS snapshots) are more efficient. Ensure the snapshot includes all data files and the journal. If using WiredTiger, take a snapshot while the instance is running or after a clean shutdown; consult the MongoDB documentation for point-in-time requirements.

## 7. User and Role Management

Managing users securely is a daily task. Here are common commands.

### 7.1 Create a User

use admin
db.createUser({
 user: "appUser",
 pwd: "STRONG_PASSWORD", // Use a password manager
 roles: [
 { role: "readWrite", db: "sales" },
 { role: "read", db: "reporting" }
 ]
}) 

### 7.2 View Users and Roles

 db.getUsers() 
 Show all roles:

db.getRoles({ showPrivileges: true }) 

### 7.3 Grant or Revoke Roles

 Grant a role:

db.grantRolesToUser("appUser", [ { role: "readWrite", db: "inventory" } ]) 
 Revoke a role:

db.revokeRolesFromUser("appUser", [ { role: "readWrite", db: "inventory" } ]) 

### 7.4 Change Password

 db.changeUserPassword("appUser", "NEW_STRONG_PASSWORD") 
 Security note : Never store passwords in scripts. Use environment variables or a secrets manager.

## 8. Common Pitfalls and How to Avoid Them

Even experienced operators encounter these mistakes. Here is how to prevent and recover from them.

### Pitfall 1: Running Destructive Commands Without Filter

- Why it happens : Rushing or assuming the filter is present.

- Impact : Data loss, especially with deleteMany({}) or updateMany({}) .

- Avoidance : Always write the filter explicitly, use deleteOne / updateOne for single-document changes, and enable protectAuditedDeletes in production.

- Recovery : Restore from backup or use the oplog to replay operations up to just before the mistake (if possible).

### Pitfall 2: Creating Indexes Without Considering Impact

- Why it happens : In development, index creation may seem instant; in production, it can block writes.

- Impact : Increased latency or downtime.

- Avoidance : Build indexes in the background (default in 4.2+) or use rolling index builds on replica sets. Monitor with currentOp .

- Recovery : Kill the index build if necessary: db.killOp(<opid>) , then consider building during low-traffic periods.

### Pitfall 3: Ignoring Replication Lag

- Why it happens : Not monitoring secondary health, or overloading the primary with write-heavy operations.

- Impact : Secondary cannot failover, read scaling suffers, potential data loss on disaster.

- Avoidance : Set up alerts for lag, optimize writes with batching, and add more capacity when needed.

- Recovery : Identify and kill long-running ops, check network, or resync the secondary from a fresh backup.

### Pitfall 4: Hardcoding Credentials in Scripts

- Why it happens : Convenience.

- Impact : Credential leaks, security breaches.

- Avoidance : Use environment variables or MongoDB's --password prompt. In code, use a secrets manager like HashiCorp Vault or AWS Secrets Manager.

- Recovery : Rotate the exposed password immediately and audit access logs.

### Pitfall 5: Misconfigured Authentication or Authorization

- Why it happens : Confusion about authentication database vs. target database.

- Impact : Users cannot connect or have excessive privileges.

- Avoidance : Always specify --authenticationDatabase when connecting. Grant roles on the specific databases needed, not blanket root in production.

- Recovery : Connect as an admin and correct roles with grantRolesToUser or revokeRolesFromUser .

## 9. Operations Checklist for Daily Administration

Use this checklist during routine operations to ensure safety and accountability. Assign an owner for each major decision.

<div class="my-stack-md overflow-x-auto">
<table class="min-w-[42rem] border-collapse text-left">
<thead><tr><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Task</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Command/Procedure</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Verification</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Owner</th><th scope="col" class="border border-outline-variant bg-surface-container-low px-4 py-3 text-left font-label-md font-semibold text-on-surface">Frequency</th></tr></thead>
<tbody><tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Check server version</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">db.version()</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Confirm expected version</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Database Administrator</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Weekly</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Review server status</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">db.serverStatus()</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Metrics within baselines</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">SRE</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Daily</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Check replication lag</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">rs.printSecondaryReplicationInfo()</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Lag &lt; 10 seconds</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Database Administrator</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Hourly (automated)</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Validate backup integrity</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">mongorestore --dryRun</code> on backup</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">No errors</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Backup Engineer</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Monthly</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Review index usage</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">$indexStats</code> aggregation</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Drop unused indexes</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Database Administrator</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Quarterly</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Audit user privileges</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant"><code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">db.getUsers()</code> and <code class="font-mono text-[0.9em] bg-surface-container px-1 py-0.5 rounded">getRoles</code></td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Least privilege applied</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Security Lead</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Monthly</td></tr>
<tr><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Test restore procedure</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Restore backup to staging</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Data integrity confirmed</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Backup Engineer</td><td class="border border-outline-variant px-4 py-3 align-top text-body-md text-on-surface-variant">Quarterly</td></tr></tbody>
</table>
</div>
Accountability : The Database Administrator owns version checks, replication lag, and index review. The Backup Engineer owns backup and restore tests. The Security Lead owns privilege audits. Each item should have a runbook and a designated backup person.

## 10. Conclusion

MongoDB basic commands with practical examples are most valuable when they are part of a disciplined operational workflow. This guide has covered version checks, safe configuration changes, CRUD, indexing, diagnostics, user management, backup/restore, and common pitfalls. Each command should be tested in a staging environment before production, with a clear rollback plan.

Start with low-risk verifications: run db.version() , db.serverStatus() , and rs.status() on your instances. Record the outputs, compare with expected baselines, and then gradually incorporate the more involved commands. By following the principles of observe, scoped change, verify, and recover, you can manage MongoDB confidently and avoid costly mistakes.

For continued learning, explore the official MongoDB documentation on command reference, security best practices, and performance tuning. Practice in a safe environment, and always keep your backups current.