What MongoDB is
TrapDon't say MongoDB lacks transactions. Single-document writes are atomic, and multi-document ones came in 4.0.
w: "majority" write, the default since 5.0, survives a failover.mongos routes each query to the right shards.w: 1 write before any secondary has it, so a failover can roll it back. Once a majority has the write, it survives.TrapDon't say MongoDB lacks transactions. Single-document writes are atomic, and multi-document ones came in 4.0.
ObjectId and Date._id. It holds a 4-byte timestamp, 5 random bytes and a 3-byte counter.doc._id.getTimestamp() TrapA typo in a collection name doesn't fail. An insert just creates a new collection.
db.users.insertOne(doc) db.users.insertMany([d1, d2])find({age: 30})findOne({age: 30})find returns a cursor. findOne returns a document, or null.find({}, {name: 1, _id: 0})find().sort({age: -1}).skip(20).limit(10) countDocuments({age: 30})updateOne({_id: 1}, {$set: {a: 1}})updateMany changes every match.replaceOne({_id: 1}, {a: 1})Fields you leave out are gone.deleteOne({_id: 1})deleteMany({a: 1})db.users.drop()TrapAn empty filter matches every document. deleteMany({}) empties the collection.
{status: {$in: ["a", "b"]}}{$or: [{a: 1}, {b: 2}]}{phone: {$exists: true}}{items: {$elemMatch: {qty: 5, ok: true}}}TrapWithout $elemMatch, two conditions on an array can match two different elements.
Asked in interviews
AskedWhat are MongoDB query operators? Provide examples.{$set: {a: 1}}{$unset: {a: 1}}{$inc: {views: 1}}{$push: {tags: "x"}}{$addToSet: {tags: "x"}}{upsert: true}$setOnInsert sets fields only on insert.TrapTwo upserts at once can both insert. A unique index on the filter fields stops that.
db.users.createIndex({email: 1}){unique: true}{cust: 1, date: -1}It serves cust alone, but not date alone.{$indexStats: {}}Drop them. Every index slows writes.TrapA range field before the sort field forces an in-memory sort.
{partialFilterExpression: {paid: true}}Queries must include that condition.{sparse: true}Prefer a partial index.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.
createIndex({tags: 1})MongoDB makes it multikey, with one entry per distinct element.{"attrs.$**": 1}It's slower than an index on named fields.TrapA compound multikey index allows only one array field per document.
.explain("executionStats") Plain explain() shows the plan without running it.COLLSCAN, or far more documents examined than returned.{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.
{title: "text"}{$text: {$search: "a b"}}A collection can have only one text index.{loc: "2dsphere"}{$near: {$geometry: pt, $maxDistance: 1000}}TrapGeoJSON puts longitude before latitude. Swap them and every distance is wrong.
{$match: {status: "paid"}}{$group: {_id: "$cust", n: {$sum: 1}}}{$project: {name: 1}}{$unwind: "$items"}$lookupSet from, localField, foreignField and as.let and $expr.TipIndex the foreignField. Every input document runs a lookup on it.
Trap$lookup joins only collections in the same database.
{$sum: "$amt"}{$avg: "$amt"}{$push: "$name"}{$addToSet: "$tag"}{$multiply: ["$p", 0.1]}{$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.
customerId in each order.TrapAn array that grows without limit eventually hits the 16MB document limit.
$lookup for a field you always showThe extended reference pattern. Copy that field into the document.Asked in interviews
AskedWhat are some common MongoDB schema design patterns?{timeseries: {timeField: "ts"}}MongoDB buckets and compresses them for you.{capped: true, size: 100000}When it's full, MongoDB deletes the oldest.TrapYou can't shard a capped collection. Expire data by age with a TTL index instead.
{$jsonSchema: {required: ["name"]}}Add it to an existing collection with collMod.validationAction: "warn"validationLevel: "moderate"Then switch to the defaults, error and strict.Asked in interviews
AskedWhat is schema validation in MongoDB, and how do you use it?s = db.getMongo().startSession() s.startTransaction() s.commitTransaction() Call s.abortTransaction() on an error.s.withTransaction(fn) TipTransient means rerun the whole transaction. Unknown means retry only the commit.
TrapAn operation run without the session isn't part of the transaction. It commits at once.
electionTimeoutMillis default.rs.stepDown(60)Writes fail until a new primary takes over.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.
primary, the default, plus primaryPreferred , secondary, secondaryPreferred and nearest.readPref("secondaryPreferred") TrapEvery mode except primary may read a secondary, which can return stale data.
Asked in interviews
AskedHow do you configure read preferences in MongoDB?{w: "majority"}The default since 5.0.{w: 1}A failover can roll it back.{j: true}readConcern("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.
Asked in interviews
AskedWhat are write concern and read concern in MongoDB?db.orders.watch() It needs a replica set or a sharded cluster.{fullDocument: "updateLookup"}{resumeAfter: token}Save each event's _id, its resume token.TrapA resume token works only while the oplog still holds it.
Asked in interviews
AskedExplain MongoDB Change Streams.sh.shardCollection("app.users", {uid: 1})sh.enableSharding() is optional since 6.0.TrapA query without the shard key goes to every shard.
{userId: "hashed"}Range queries then go to every shard.{deviceId: 1, ts: 1}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.
Asked in interviews
AskedHow do you choose a good shard key?sh.getBalancerState() sh.setBalancerState(false) activeWindow limits it to quiet hours.Asked in interviews
AskedWhat is chunk migration and how does the balancer work?db.setProfilingLevel(1, {slowms: 100})db.system.profile.find() db.setProfilingLevel(2) It slows the server.db.currentOp()TipOn a busy server, read the slow query log instead. The profiler adds load.
db.serverStatus().wiredTiger.cache TrapDon't raise the cache past its default. The filesystem cache and connections need memory too.
db.serverStatus() Memory, connections, locks and more.mongostatmongotopgrep '"Slow query"' mongod.logs for severity, c for component and msg for the message.mongod --authIt's off by default.userAdminAnyDatabase .db.createUser({user: "app", pwd: "pw", roles: ["readWrite"]})admin--authenticationDatabase adminDrivers use authSource=admin .read or readWrite for apps, dbAdmin for indexes and stats, and root for everything.db.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.
net.bindIp: 127.0.0.1,10.0.0.5The default is localhost only.net.tls.mode: requireTLSAsked in interviews
AskedHow do you secure MongoDB in production?mongodump --db shopmongorestore dump/mongodump --oplogmongorestore --oplogReplaymongorestore --drop dump/db.fsyncLock()db.fsyncUnlock() Lock a secondary, snapshot its disk, then unlock.TrapOn a sharded cluster, stop the balancer and lock it with fsyncLock() through mongos before mongodump. That needs 7.1+.
Asked in interviews
AskedHow do you backup and restore MongoDB databases?Nothing matches. Try a shorter word, or clear the search.
With Pro, you can:
Already have Pro? Sign in