📡 You're offline — showing cached content
New version available!
Quick Access
MongoDB Reference

MongoDB NoSQL

Document storage, aggregation, and query patterns.

All Topics

CRUD & Querying

insertOne / insertMany
Insert document(s). Returns acknowledged:true and insertedId(s). _id auto-generated as ObjectId.
Example: db.users.insertMany([{name:'Alice'},{name:'Bob'}], {ordered:false});
findOne / find().toArray()
findOne returns first match or null. find returns cursor — call .toArray() or iterate.
Example: const user = await db.users.findOne({email:'a@b.com'}, {projection:{password:0}});
Query operators: $eq $gt $in
$eq (default), $ne, $gt, $gte, $lt, $lte, $in, $nin, $exists, $type, $regex, $mod.
Example: db.orders.find({status:{$in:['pending','processing']}, total:{$gt:100}});
Logical: $and $or $not $nor
Combine query conditions. $and is implicit when using multiple fields in one object.
Example: db.products.find({$or:[{stock:0},{$and:[{price:{$gt:100}},{sale:true}]}]});
Projection
Include (1) or exclude (0) fields. Can't mix include/exclude except for _id.
Example: db.users.find({},{name:1, email:1, _id:0}); // only name and email
sort / limit / skip
Chain cursor methods. Always sort before limit/skip for consistent pagination.
Example: db.posts.find().sort({createdAt:-1}).skip(20).limit(10);
$elemMatch
Match array elements where multiple conditions apply to the SAME element.
Example: db.courses.find({grades:{$elemMatch:{score:{$gte:90},subject:'Math'}}});
deleteOne / deleteMany
Remove matching documents. Returns deletedCount. findOneAndDelete returns the deleted doc.
Example: const {deletedCount} = await db.sessions.deleteMany({expiresAt:{$lt:new Date()}});

Update Operators

$set / $unset
Set field value / remove field entirely. $setOnInsert sets only on upsert insert (not update).
Example: db.users.updateOne({_id}, {$set:{name:'Bob',$unset:{tempCode:''}}, $currentDate:{updatedAt:true}});
$inc / $mul
Atomic increment/decrement / multiply a field value. Cannot set to zero with $mul — use $set.
Example: db.products.updateOne({_id}, {$inc:{stock:-quantity,$mul:{price:1.1}}});
$push / $addToSet
Push to array / push only if value doesn't exist (deduplicate). Add $each for multiple values.
Example: db.post.updateOne({_id}, {$addToSet:{tags:{$each:['nodejs','api']}}});
$pull / $pop
$pull removes matching elements from array. $pop removes first (-1) or last (1) element.
Example: db.cart.updateOne({_id}, {$pull:{items:{productId:{$in:removedIds}}}});
$ positional / $[] / $[filter]
Update matched array element / all elements / filtered elements in nested arrays.
Example: db.orders.updateOne({_id,items.product:pid},{$set:{'items.$.qty':newQty}});
upsert: true
Insert document if no match found. Combine with $setOnInsert for upsert-specific fields.
Example: db.stats.updateOne({date:today},{$inc:{views:1},$setOnInsert:{createdAt:new Date()}},{upsert:true});
findOneAndUpdate
Atomic find + update + return document. returnDocument:'after' returns updated doc.
Example: const updated = await db.jobs.findOneAndUpdate({status:'queued'},{$set:{status:'processing',startedAt:new Date()}},{sort:{priority:-1},returnDocument:'after'});

Aggregation Pipeline

$match (filter stages)
Always put $match first to filter early before expensive operations.
Example: { $match: { status: 'active', createdAt: { $gte: ISODate('2024-01-01') } } }
$group with accumulators
Accumulators: $sum, $avg, $min, $max, $push, $addToSet, $first, $last, $count.
Example: { $group: { _id: '$category', total: { $sum: '$amount' }, avg: { $avg: '$rating' } } }
$lookup (JOIN)
Left outer join from one collection to another (or same collection). Pipeline variant for complex conditions.
Example: { $lookup: { from: 'products', localField: 'productId', foreignField: '_id', as: 'product' } }
$unwind
Deconstruct array field — creates one document per array element. Use preserveNullAndEmptyArrays.
Example: { $unwind: { path: '$tags', preserveNullAndEmptyArrays: true } }
$project / $addFields
$project shapes output (include/exclude/rename). $addFields adds computed fields without removing others.
Example: { $addFields: { fullName: { $concat: ['$firstName', ' ', '$lastName'] }, age: { $dateDiff: { startDate: '$dob', endDate: '$$NOW', unit: 'year' } } } }
$facet (multi-aggregation)
Run multiple aggregation pipelines in one pass — search results + total count + faceted filters.
Example: { $facet: { data: [{$skip:skip},{$limit:20}], total: [{$count:'n'}], categories: [{$group:{_id:'$cat'}}] } }
$bucket / $bucketAuto
Group documents into histogram buckets. $bucketAuto creates N evenly distributed buckets.
Example: { $bucketAuto: { groupBy: '$price', buckets: 5, output: { count: { $sum: 1 }, avg: { $avg: '$price' } } } }

Indexes & Performance

createIndex({field:1})
Create ascending (1) or descending (-1) single-field index. background:true avoids blocking (deprecated in 4.2+).
Example: db.users.createIndex({email:1},{unique:true,sparse:true});
Compound indexes
Multi-field index — order matters! ESR rule: Equality fields → Sort fields → Range fields.
Example: db.logs.createIndex({userId:1,level:1,createdAt:-1}); // ESR rule
Text index / $text
Full-text search across string fields. One text index per collection. Atlas Search is more powerful.
Example: db.articles.createIndex({title:'text',body:'text'}); db.articles.find({$text:{$search:'mongodb aggregation'}},{score:{$meta:'textScore'}});
TTL index (expireAfterSeconds)
Auto-delete documents after N seconds based on a Date field — sessions, cache, temp data.
Example: db.sessions.createIndex({createdAt:1},{expireAfterSeconds:86400});
explain("executionStats")
Analyze query execution — check COLLSCAN vs IXSCAN, nReturned, totalDocsExamined.
Example: db.users.find({email:'x@y.com'}).explain('executionStats');
Transactions (multi-doc)
ACID transactions across multiple documents/collections/databases (replica sets required).
Example: const session = client.startSession(); session.withTransaction(async () => { await col1.updateOne({},{$inc:{val:1}},{session}); await col2.insertOne({log:'done'},{session}); });