mongosh CLI
mongosh is MongoDB’s modern shell — a fully scriptable Node.js REPL. It replaces the legacy mongo shell; everything you used to do in JS commands still works, plus async/await, modern syntax, and richer plugins.
Connect, query, admin, scripts
EXAMPLE
// 1) Install
// macOS — brew install mongosh
// Linux — package or download from mongodb.com/try/download/shell
// Windows — winget install MongoDB.Shell
// 2) Connect
mongosh
mongosh "mongodb://localhost:27017"
mongosh "mongodb+srv://user:pw@cluster.mongodb.net/myapp"
mongosh --apiVersion 1 --username admin --authenticationDatabase admin --eval 'db.runCommand({ping: 1})'
// In Atlas: use the connection string from the Atlas UI; it includes TLS + SRV.
// 3) Pick a database + collection
use shop // switches current db; creates lazily on first write
db.getName() // 'shop'
show dbs // list databases
show collections // list collections in current db
// 4) Insert
db.orders.insertOne({ totalCents: 4999, status: 'pending', createdAt: new Date() })
db.orders.insertMany([
{ totalCents: 1299, status: 'paid' },
{ totalCents: 8999, status: 'paid', vip: true },
])
// 5) Find
db.orders.findOne() // any one
db.orders.findOne({ status: 'paid' })
db.orders.find({ status: 'paid' }).toArray() // materialise
db.orders.find({ totalCents: { $gt: 5000 } }).count()
db.orders.find().sort({ createdAt: -1 }).limit(10).pretty()
// 6) Update
db.orders.updateOne(
{ _id: ObjectId('…') },
{ $set: { status: 'shipped', shippedAt: new Date() } },
)
db.orders.updateMany({ status: 'paid' }, { $inc: { reminderCount: 1 } })
db.orders.replaceOne({ _id }, fullDoc) // replace; loses fields not in fullDoc
// 7) Delete
db.orders.deleteOne({ _id: ObjectId('…') })
db.orders.deleteMany({ status: 'cart', updatedAt: { $lt: hoursAgo(48) } })
// 8) Aggregate — the powerhouse
db.orders.aggregate([
{ $match: { status: 'paid', createdAt: { $gte: ISODate('2024-01-01') } } },
{ $group: { _id: '$customerId', revenue: { $sum: '$totalCents' }, n: { $sum: 1 } } },
{ $sort: { revenue: -1 } },
{ $limit: 10 },
])
// 9) Indexes
db.orders.createIndex({ status: 1, createdAt: -1 })
db.orders.createIndex({ email: 1 }, { unique: true })
db.orders.getIndexes()
db.orders.dropIndex('status_1_createdAt_-1')
// 10) Explain
db.orders.find({ status: 'paid' }).explain('executionStats')
// Look at: totalDocsExamined, executionTimeMillis, winningPlan.stage ('COLLSCAN' = no index)
// 11) Async / await — mongosh is async under the hood
const recent = await db.orders.find({ status: 'paid' })
.sort({ createdAt: -1 }).limit(5).toArray();
print(recent.length);
for await (const doc of db.orders.find()) {
if (doc.totalCents > 10000) print(doc._id);
}
// 12) Variables + functions in the shell
const since = ISODate('2024-01-01');
db.orders.countDocuments({ createdAt: { $gte: since } });
function shipAll(filter) {
return db.orders.updateMany(
{ ...filter, status: 'paid' },
{ $set: { status: 'shipped', shippedAt: new Date() } },
);
}
await shipAll({ priorityShipping: true });
// 13) Scripts — non-interactive
// migrate.js
use shop
db.orders.updateMany(
{ status: 'paid', shippedAt: { $exists: false } },
{ $set: { reviewNeeded: true } },
);
mongosh "mongodb://localhost" --quiet --file migrate.js
mongosh "mongodb://localhost" --quiet --eval 'db.users.countDocuments()'
// 14) Administration
use admin
db.runCommand({ ping: 1 })
db.runCommand({ serverStatus: 1 })
db.runCommand({ replSetGetStatus: 1 })
db.adminCommand({ listDatabases: 1 })
// Users + roles
db.createUser({
user: 'app',
pwd: passwordPrompt(), // interactive prompt
roles: [{ role: 'readWrite', db: 'shop' }],
})
db.changeUserPassword('app', passwordPrompt())
db.dropUser('legacy')
// 15) Backup / restore
mongodump --uri='mongodb://localhost' --db=shop --out=/backup
mongorestore --uri='mongodb://localhost' /backup
mongoexport --uri='mongodb://localhost' -d shop -c orders --out=orders.json
mongoimport --uri='mongodb://localhost' -d shop -c orders --file orders.json
// Run from your OS shell, not mongosh.
// 16) Profiler — slow queries
db.setProfilingLevel(1, { slowms: 100 }) // log queries > 100ms
db.system.profile.find().sort({ ts: -1 }).limit(10).pretty()
db.setProfilingLevel(0) // turn off
// 17) Useful shortcuts
ObjectId() // generate a new id
ObjectId('64fa…').getTimestamp() // when was this id created?
UUID()
ISODate('2024-01-15T03:21:00Z')
NumberDecimal('19.99') // arbitrary-precision decimal for money
NumberLong('9007199254740993') // 64-bit int for ids beyond JS safe range
// 18) Cluster + replica set
rs.status()
rs.initiate()
sh.status() // sharded cluster
sh.shardCollection('shop.orders', { customerId: 1 })
// 19) Plugins / Snippets
snippet install analyze-schema // install community snippets
snippet ls
// 20) Common bugs
// • Connection string missing tls or authSource → mysterious auth failures
// • Using = instead of === in find filters → syntax error in newer mongosh
// • Forgetting .toArray() / for-await — find() returns a cursor
// • COLLSCAN in explain — no index used; check filter shape + index keys
// • Storing money as Number → rounding bugs; use NumberDecimal
// • Running a 'mongo' command in mongosh — most legacy syntax works, some doesn't
// • Editing live data without backups — mongodump first, then change
Why it matters
Use mongosh for everything — quick queries, scripts, and admin tasks. It’s a real JS runtime, so you can write loops, await cursors, and stash helpers in .mongoshrc.js. For anything you’ll repeat, drop the commands into a .js file and run it with --file; for anything destructive, dump first.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Discussion
Loading…