LearnThatStack Ace your next interview

MongoDB

Commands for MongoDB 7.0+ in mongosh Checked Oct 2026 95 commands

The model

  • A document is one record, stored as binary JSON called BSON, up to 16MB. A collection holds documents of any shape.
  • A write to one document is atomic, all or nothing. Multi-document transactions work too, but cost more.
  • A replica set's primary takes every write and logs it in the oplog. Secondaries copy the oplog asynchronously.
  • Write concern sets how many members confirm a write. A w: "majority" write, the default since 5.0, survives a failover.
  • Sharding splits a collection across replica sets by a shard key. mongos routes each query to the right shards.
AppdriverPrimarytakes all writesSecondarycopies the oplogWRITEinsertOnew: 1 ack can roll backoplog copied asyncconfirmsmajority ack survives failoverREADsecondary read may be stale
The primary confirms a w: 1 write before any secondary has it, so a failover can roll it back. Once a majority has the write, it survives.

Documents & BSON

what MongoDB stores, and how it's organized

What MongoDB is

Say what MongoDB isA document database with a flexible schema, replica sets and sharding.
Map SQL terms to MongoDBA table is a collection, a row is a document, and a column is a field.
Choose MongoDB over SQLFor data that changes shape, or must scale out. Pick SQL for heavy joins.

TrapDon't say MongoDB lacks transactions. Single-document writes are atomic, and multi-document ones came in 4.0.

BSON and ObjectId

Say how BSON differs from JSONBSON is binary and adds types like ObjectId and Date.
Read an ObjectId's 12 bytesThe default _id. It holds a 4-byte timestamp, 5 random bytes and a 3-byte counter.
Get the time an ObjectId was madedoc._id.getTimestamp()
Name the three levels of dataA database holds collections, which hold documents.

TrapA typo in a collection name doesn't fail. An insert just creates a new collection.

CRUD & operators

read, write and change documents

Insert, find, update, delete

Insert one document, or manydb.users.insertOne(doc)db.users.insertMany([d1, d2])
Find every match, or the firstfind({age: 30})findOne({age: 30})find returns a cursor. findOne returns a document, or null.
Return only some fieldsfind({}, {name: 1, _id: 0})
Sort, skip and limit the resultsfind().sort({age: -1}).skip(20).limit(10)
Count the documents that matchcountDocuments({age: 30})
Change fields in the first matchupdateOne({_id: 1}, {$set: {a: 1}})updateMany changes every match.
Replace a whole documentreplaceOne({_id: 1}, {a: 1})Fields you leave out are gone.
Delete the first match, or every matchdeleteOne({_id: 1})deleteMany({a: 1})
Drop a collectiondb.users.drop()

TrapAn empty filter matches every document. deleteMany({}) empties the collection.

Query operators

Match any value in a list{status: {$in: ["a", "b"]}}
Match either of two conditions{$or: [{a: 1}, {b: 2}]}
Find documents that have a field{phone: {$exists: true}}
Make one array element meet both conditions{items: {$elemMatch: {qty: 5, ok: true}}}

TrapWithout $elemMatch, two conditions on an array can match two different elements.

Update operators and upsert

Set a field, or remove it{$set: {a: 1}}{$unset: {a: 1}}
Add to a number field{$inc: {views: 1}}
Append to an array, or add only if missing{$push: {tags: "x"}}{$addToSet: {tags: "x"}}
Update, or insert if nothing matches{upsert: true}$setOnInsert sets fields only on insert.

TrapTwo upserts at once can both insert. A unique index on the filter fields stops that.

Indexes & query plans

make queries fast, and check how they run

Single field and compound indexes

Index a field you filter or sort ondb.users.createIndex({email: 1})
Reject duplicate values{unique: true}
Index several fields together{cust: 1, date: -1}It serves cust alone, but not date alone.
Order a compound index's fieldsEquality, then sort, then range. That's the ESR rule.
Find indexes no query uses{$indexStats: {}}Drop them. Every index slows writes.

TrapA range field before the sort field forces an in-memory sort.

Partial, sparse and TTL indexes

Index only documents that match a filter{partialFilterExpression: {paid: true}}Queries must include that condition.
Index only documents that have the field{sparse: true}Prefer a partial index.
Delete documents an hour after createdAt{expireAfterSeconds: 3600}MongoDB deletes expired ones every 60 seconds.

TrapA TTL index must be a single-field index on a date. _id can't have one.

Read explain() output

Run a query and count what it examined.explain("executionStats")Plain explain() shows the plan without running it.
Spot a missing indexLook for COLLSCAN, or far more documents examined than returned.
Answer a query from the index alone{title: 1, _id: 0}Filter and project only indexed fields. That's a covered query.

TrapA covered query must leave out _id, because _id isn't in the index.

Aggregation pipeline

filter, group, reshape and join on the server

Pipeline stages and $lookup

Filter first, so the pipeline can use an index{$match: {status: "paid"}}
Count orders per customer{$group: {_id: "$cust", n: {$sum: 1}}}
Keep, drop or compute fields{$project: {name: 1}}
Turn each array element into its own document{$unwind: "$items"}
Join documents from another collection$lookupSet from, localField, foreignField and as.
Join on any conditionUse the pipeline form, with let and $expr.

TipIndex the foreignField. Every input document runs a lookup on it.

Trap$lookup joins only collections in the same database.

Accumulators and expressions

Total or average a field per group{$sum: "$amt"}{$avg: "$amt"}
Collect values, or only distinct ones{$push: "$name"}{$addToSet: "$tag"}
Compute a value from fields{$multiply: ["$p", 0.1]}
Pick a value by a condition{$cond: [{$gte: ["$age", 18]}, "adult", "minor"]}

Tip$addToSet on an array field adds whole arrays. $unwind the array first to collect its elements.

TrapAn expression can't read a field computed in the same stage. Use it in the next stage.

Schema design

shape documents around how the app reads them

Schema design patterns

Store a sensor's readings by the hourThe bucket pattern. One document per sensor per hour.
Stop recounting totals on every readThe computed pattern. Update totals as you write.
Skip a $lookup for a field you always showThe extended reference pattern. Copy that field into the document.
Keep a huge array out of the main documentThe subset pattern. Keep only the latest few there.

Time series, capped and GridFS

Store measurements over time (5.0+){timeseries: {timeField: "ts"}}MongoDB buckets and compresses them for you.
Keep only the newest log entries{capped: true, size: 100000}When it's full, MongoDB deletes the oldest.
Store a file over 16MBUse GridFS. It splits files into 255KB chunks.

TrapYou can't shard a capped collection. Expire data by age with a TTL index instead.

Schema validation

Require fields and types{$jsonSchema: {required: ["name"]}}Add it to an existing collection with collMod.
Start with soft rules while old data migratesvalidationAction: "warn"validationLevel: "moderate"Then switch to the defaults, error and strict.

Transactions

change several documents all or nothing

Multi-document transactions

Say where transactions workReplica sets since 4.0, sharded clusters since 4.2. They read from the primary.
Start a transaction, then commit its = db.getMongo().startSession()s.startTransaction()s.commitTransaction()Call s.abortTransaction() on an error.
Let the driver retry for yous.withTransaction(fn)
Name the default time and lock limits60 seconds to finish, and 5 ms to wait for a lock.
Handle a write conflictRetry. Another write changed the same document first.
Say what cross-shard writes addA two-phase commit. An overlapping chunk migration aborts them.

TipTransientTransactionError means rerun the whole transaction. UnknownTransactionCommitResult means retry only the commit.

TrapAn operation run without the session isn't part of the transaction. It commits at once.

Replica sets & consistency

copies, failover, and how fresh each read is

Replica sets, elections and the oplog

Name the member rolesA primary takes writes and secondaries copy them. An arbiter votes but holds no data.
Pick how many membersAt least three. Keep an odd number of voters, at most 7.
Say when an election startsWhen the primary is silent for 10 seconds, the electionTimeoutMillis default.
Say who winsThe first member to get a majority of votes.
Hand off the primary for maintenancers.stepDown(60)Writes fail until a new primary takes over.
Say what the oplog isA capped collection, local.oplog.rs, that logs every change. Secondaries replay it.

TrapThe oplog window is the time the oplog covers. A secondary that falls further behind needs a full resync.

Read preference

Name the five modesprimary, the default, plus primaryPreferred, secondary, secondaryPreferred and nearest.
Take reads off the primaryreadPref("secondaryPreferred")

TrapEvery mode except primary may read a secondary, which can return stale data.

Write concern and read concern

Confirm a write on a majority of members{w: "majority"}The default since 5.0.
Confirm on the primary alone{w: 1}A failover can roll it back.
Also wait for the on-disk journal{j: true}
Read only data a majority hasreadConcern("majority")local, the default, can return data a failover rolls back.

TipFor CAP, MongoDB is CP only with majority writes and linearizable reads on the primary. Secondary reads may be stale.

Trapwtimeout returns an error but doesn't undo the write.

Change streams

Watch a collection for changesdb.orders.watch()It needs a replica set or a sharded cluster.
Get the whole document on updates{fullDocument: "updateLookup"}
Resume after a restart{resumeAfter: token}Save each event's _id, its resume token.

TrapA resume token works only while the oplog still holds it.

Sharding

split a collection across many servers

Sharded clusters

appmongosconfigshard 1shard 2shard 3
routingmongos routes queries with metadata from the config servers. Each shard is a replica set.
Decide when to shardWhen data or writes outgrow one replica set.
Shard a collectionsh.shardCollection("app.users", {uid: 1})sh.enableSharding() is optional since 6.0.
Say what config servers storeWhich shard holds each chunk, plus shard keys and users.
Say what happens if the config primary failsMetadata turns read-only, so chunks stop moving. Reads and writes go on.

TrapA query without the shard key goes to every shard.

Choose a shard key

Judge a shard keyHigh cardinality, low frequency, not always increasing, and present in most queries.
Spread an increasing key evenly{userId: "hashed"}Range queries then go to every shard.
Keep each device's readings together{deviceId: 1, ts: 1}
Change a bad shard key (5.0+)sh.reshardCollection("app.users", {cid: 1})Test a key first with analyzeShardKey (7.0+).

TrapA key that only grows, like a timestamp or ObjectId, sends every insert to one shard.

Chunks and the balancer

Say what a chunk isA range of shard key values, 128MB by default.
Say when the balancer moves chunksWhen the data per shard differs by three chunk sizes, 384MB by default.
Check or pause the balancersh.getBalancerState()sh.setBalancerState(false)activeWindow limits it to quiet hours.

Performance & monitoring

find slow queries, and keep hot data in RAM

Find slow queries

Record operations slower than 100 msdb.setProfilingLevel(1, {slowms: 100})
Read what the profiler recordeddb.system.profile.find()
Record every operationdb.setProfilingLevel(2)It slows the server.
See operations running nowdb.currentOp()
Speed up a slow applicationMeasure first. Then fix indexes, queries, schema and RAM.

TipOn a busy server, read the slow query log instead. The profiler adds load.

WiredTiger and memory

Name the default storage engineWiredTiger, since 3.2. It has document-level concurrency and compression.
Say how WiredTiger survives a crashCheckpoints every 60 seconds, plus the journal.
Say how big the cache is by default50% of the RAM above 1GB, or 256MB if that's larger.
Check cache use and evictionsdb.serverStatus().wiredTiger.cache
Keep the working set in RAMThe data and indexes your common queries use. Page faults rise when it doesn't fit.

TrapDon't raise the cache past its default. The filesystem cache and connections need memory too.

Security & backups

control access, and get your data back

Users, roles and authentication

Turn on access controlmongod --authIt's off by default.
Create the first admin userConnect over localhost and give it userAdminAnyDatabase.
Create a user for one appdb.createUser({user: "app", pwd: "pw", roles: ["readWrite"]})
Log in as a user stored in admin--authenticationDatabase adminDrivers use authSource=admin.
Pick a built-in roleread or readWrite for apps, dbAdmin for indexes and stats, and root for everything.
Give a user another roledb.grantRolesToUser("app", ["read"])revokeRolesFromUser takes one away.

TipSCRAM is the default mechanism. X.509 certificate users live in the $external database.

TrapTurn on access control before the server listens on anything but localhost.

Secure a production deployment

Listen only on the networks apps usenet.bindIp: 127.0.0.1,10.0.0.5The default is localhost only.
Require TLS on every connectionnet.tls.mode: requireTLS
Encrypt data files on diskMongoDB Enterprise does this, with keys from a KMIP server.
Hide sensitive fields from the serverClient-side field level encryption, or Queryable Encryption (7.0+).

Back up and restore

Dump a database, then restore itmongodump --db shopmongorestore dump/
Include writes made during the dumpmongodump --oplogmongorestore --oplogReplay
Replace collections with the backup's copymongorestore --drop dump/
Back up a large data set fastdb.fsyncLock()db.fsyncUnlock()Lock a secondary, snapshot its disk, then unlock.
Restore to a point in timeUse managed backups in Atlas or Ops Manager. They copy the oplog continuously.

TrapOn a sharded cluster, stop the balancer and lock it with fsyncLock() through mongos before mongodump. That needs 7.1+.

Found this useful? Pass it on.
Pro · $10/mo

This sheet stays free. With Pro, you can:

  • Every answer on this sheet. Read the full answer to all 57 questions it links, not just the 7 free ones.
  • My sheet. The cards you star and the ones you miss in Quiz me, from every sheet, on one page to quiz and print.
  • PDFs. Download this sheet and My sheet, laid out for A4, with every question a link to its answer.
  • The rest of Pro. Every answer in the question library, and 1,000 AI credits a month.