Skip to content
Commitpedia
Log in Join & edit

mongosh cheat sheet: CRUD, indexes and explain()

The mongosh commands you use every day: switching databases, inserting, querying, updating and deleting documents, creating indexes and checking a query plan with explain().

Not checked by a trusted editor yet Last edited Outdated?

Edit history of mongosh cheat sheet: CRUD, indexes and explain(): 1 recorded edit
Edit history · 1 edit
Type
Article
Edits
1
Editors
1
First issued
15 Oct 2026
Last edit
15 Oct 2026
Reading
3 min

mongosh is the MongoDB Shell. Run it without options to connect to a server on localhost port 27017, or pass a connection string. All examples below use a sample shop database with a customers collection.

mongosh                                            # local server, port 27017
mongosh "mongodb://db1.example.com:27017/shop"      # remote server, database shop
mongosh "mongodb://[email protected]:27017/shop?authSource=admin"   # prompts for the password

Navigate

show dbs                 // list databases
use shop                 // switch (created on first write)
show collections         // list collections in the current database
db.getName()             // which database am I in?

Create

db.customers.insertOne({ name: "Ada", city: "Springfield", orders: 3 })

db.customers.insertMany([
  { name: "Ben", city: "Shelbyville", orders: 0 },
  { name: "Cy",  city: "Springfield", orders: 12, vip: true }
])

Inserting into a collection that does not exist creates it.

Read

db.customers.find()                                   // everything (mongosh shows a batch)
db.customers.find({ city: "Springfield" })            // equality
db.customers.find({ orders: { $gte: 5 } })            // comparison: $gt $gte $lt $lte $ne
db.customers.find({ city: { $in: ["Springfield", "Ogdenville"] } })
db.customers.find({ city: "Springfield", vip: true }) // implicit AND
db.customers.find({ $or: [ { vip: true }, { orders: { $gt: 10 } } ] })

db.customers.find({ city: "Springfield" }, { name: 1, _id: 0 })   // projection: only name
db.customers.find().sort({ orders: -1 }).limit(5)                  // top 5 by orders
db.customers.findOne({ name: "Ada" })
db.customers.countDocuments({ city: "Springfield" })

For equality checks on one field, prefer $in over a chain of $or conditions.

Update

db.customers.updateOne(
  { name: "Ada" },
  { $set: { city: "Capital City" }, $inc: { orders: 1 }, $currentDate: { updatedAt: true } }
)

db.customers.updateMany({ orders: 0 }, { $set: { status: "inactive" } })

db.customers.updateOne(                 // insert if no match
  { name: "Dee" },
  { $set: { city: "Springfield" } },
  { upsert: true }
)

db.customers.replaceOne({ name: "Ben" }, { name: "Ben", city: "Ogdenville", orders: 1 })

Always use an update operator such as $set with updateOne and updateMany. replaceOne is different: it swaps the whole document (except _id) for the one you pass.

Delete

Deletes cannot be undone. Run the same filter with find() or countDocuments() first and check the number before you delete.

db.customers.countDocuments({ status: "inactive" })   // check first
db.customers.deleteMany({ status: "inactive" })
db.customers.deleteOne({ name: "Dee" })

An empty filter matches everything: deleteMany({}) empties the whole collection.

Indexes

db.customers.createIndex({ city: 1 })                 // single field, ascending
db.customers.createIndex({ city: 1, orders: -1 })     // compound index
db.customers.createIndex({ email: 1 }, { unique: true })
db.customers.getIndexes()
db.customers.dropIndex({ city: 1 })

A compound index also serves queries on its prefix: { city: 1, orders: -1 } helps queries on city alone, but not queries on orders alone. When you design compound indexes, follow the ESR guideline: fields used for Equality first, then Sort fields, then Range fields. A compound index can contain up to 32 fields.

Check a query plan with explain()

db.customers.find({ city: "Springfield" }).sort({ orders: -1 }).explain("executionStats")

explain() without an argument uses queryPlanner mode, which shows the chosen plan without running the query. "executionStats" also runs it and reports numbers. Look at these parts of the output:

  • winningPlan stages: COLLSCAN means a full collection scan; IXSCAN means an index was used; FETCH retrieves the documents the index pointed to.
  • A SORT stage means MongoDB sorted the results in memory because no index gave the order.
  • nReturned: documents returned.
  • totalKeysExamined and totalDocsExamined: index entries and documents looked at. Ideally they are close to nReturned.
  • executionTimeMillis: time for plan selection and execution, without network transfer.

A typical tuning loop: run explain, see COLLSCAN with totalDocsExamined far above nReturned, add an index that matches the filter and sort, and run explain again to confirm an IXSCAN.

Official documentation

See also

History

Every saved edit is kept. The plot on the sleeve draws one line per edit. Open any edit to see exactly what changed.

  1. Commitpedia +4,812 chars

Report a problem

Something wrong, unsafe or copied? Tell the editors.
What is wrong?