ID: I202601271142
Status: idea
Tags: MongoDB
MongoDB Cheatsheet
1) Core Queries
- Equal (explicit operator)
db.collection.find({ id: { $eq: 12 } })- Equal (implicit ā preferred to reduce operator injection surface)
db.collection.find({ id: 12 })- Not equal
db.collection.find({ id: { $ne: 12 } })- Greater than
db.collection.find({ id: { $gt: 12 } })- Greater than or equal
db.collection.find({ id: { $gte: 12 } })- Less than
db.collection.find({ id: { $lt: 12 } })- Less than or equal
db.collection.find({ id: { $lte: 12 } })- Between (exclusive)
db.collection.find({ id: { $gt: 12, $lt: 100 } })- Between (inclusive)
db.collection.find({ id: { $gte: 12, $lte: 100 } })- In list
db.collection.find({ status: { $in: ["new", "active"] } })- Not in list
db.collection.find({ status: { $nin: ["archived", "deleted"] } })- Exists (field present)
db.collection.find({ archivedAt: { $exists: true } })- Does not exist (field missing)
db.collection.find({ archivedAt: { $exists: false } })- Type check (e.g., string)
db.collection.find({ name: { $type: "string" } })- Regex (case-sensitive)
db.collection.find({ name: { $regex: "^Jo" } })- Regex (case-insensitive)
db.collection.find({ name: { $regex: "^jo", $options: "i" } })- AND across fields (implicit AND)
db.collection.find({ status: "active", role: "admin" })- AND with $and (explicit)
db.collection.find({
$and: [{ status: "active" }, { role: "admin" }]
})- OR
db.collection.find({
$or: [{ status: "active" }, { role: "admin" }]
})- NOR
db.collection.find({
$nor: [{ status: "active" }, { role: "admin" }]
})- NOT (negate a condition)
db.collection.find({
score: { $not: { $gte: 70 } }
})- Element match in arrays
db.collection.find({
tags: { $elemMatch: { $in: ["red", "blue"] } }
})- Array contains value (simple)
db.collection.find({ tags: "blue" })- Array contains all values
db.collection.find({ tags: { $all: ["red", "blue"] } })- Array size exactly
db.collection.find({ tags: { $size: 3 } })- Match by ObjectId
db.collection.find({ _id: ObjectId("64f1a2b3c4d5e6f7890abc12") })- Date range
db.collection.find({
createdAt: {
$gte: ISODate("2025-01-01T00:00:00Z"),
$lt: ISODate("2026-01-01T00:00:00Z")
}
})- Text search (requires text index)
db.collection.find({ $text: { $search: "exact phrase" } })- Projection (include/exclude fields)
db.collection.find(
{ status: "active" },
{ name: 1, email: 1, _id: 0 }
)- Sort, skip, limit
db.collection.find({ status: "active" })
.sort({ createdAt: -1 })
.skip(20)
.limit(10)- Distinct values
db.collection.distinct("status", { orgId: 42 })- Count documents
db.collection.countDocuments({ status: "active" })2) Inserts
- Insert one
db.collection.insertOne({
name: "Alice",
status: "active",
createdAt: new Date()
})- Insert many
db.collection.insertMany(
[
{ name: "Bob", status: "pending" },
{ name: "Carol", status: "active" }
],
{ ordered: false } // continue on errors
)- Insert with client-side _id
db.collection.insertOne({ _id: ObjectId(), email: "u@example.com" })- Insert with write concern
db.collection.insertOne(
{ name: "Durga" },
{ writeConcern: { w: "majority", wtimeout: 5000 } }
)3) Updates and Deletes
- Update one (set fields)
db.collection.updateOne(
{ _id: ObjectId("64f1a2b3c4d5e6f7890abc12") },
{ $set: { status: "active" } }
)- Update many (increment)
db.collection.updateMany(
{ status: "active" },
{ $inc: { loginCount: 1 } }
)- Upsert
db.collection.updateOne(
{ email: "user@example.com" },
{
$setOnInsert: { createdAt: new Date() },
$set: { status: "pending" }
},
{ upsert: true }
)- Find one and update (return document)
db.collection.findOneAndUpdate(
{ email: "user@example.com" },
{ $set: { status: "active" } },
{ returnDocument: "after" }
)- Set if missing (upsert pattern)
db.collection.updateOne(
{ email: "a@b.com" },
{ $setOnInsert: { createdAt: new Date() } },
{ upsert: true }
)- Add to set (no duplicates)
db.collection.updateOne({ _id: id }, { $addToSet: { tags: "blue" } })- Push with sort/limit (bounded array)
db.collection.updateOne(
{ _id: id },
{
$push: {
events: {
$each: [{ t: new Date(), type: "login" }],
$sort: { t: -1 },
$slice: 100
}
}
}
)- Rename and unset fields
db.collection.updateMany({}, { $rename: { oldName: "newName" } })
db.collection.updateMany({ obsolete: true }, { $unset: { obsolete: "" } })- Update with arrayFilters
db.collection.updateOne(
{ _id: id },
{ $set: { "items.$[it].qty": 0 } },
{ arrayFilters: [{ "it.qty": { $lt: 0 } }] }
)- Delete one
db.collection.deleteOne({ status: "inactive" })- Delete many
db.collection.deleteMany({ status: { $in: ["inactive", "deleted"] } })4) Indexes
- Create index
db.collection.createIndex(
{ email: 1 },
{ unique: true, name: "idx_email_unique" }
)- Compound index (equality first, then range, then sort)
db.collection.createIndex({ orgId: 1, status: 1, createdAt: -1 })- Partial index
db.collection.createIndex(
{ email: 1 },
{ unique: true, partialFilterExpression: { deletedAt: { $exists: false } } }
)- Sparse vs. partial
db.collection.createIndex({ phone: 1 }, { sparse: true })- Text index
db.collection.createIndex(
{ name: "text", bio: "text" },
{ default_language: "english" }
)- Wildcard index (schema-flexible)
db.collection.createIndex({ "meta.$**": 1 })- TTL index (auto-expire)
db.collection.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 })- View indexes
db.collection.getIndexes()5) Aggregation Framework
- Basic pipeline
db.collection.aggregate([
{ $match: { status: "active" } },
{ $project: { name: 1, year: { $year: "$createdAt" } } },
{ $group: { _id: "$year", count: { $sum: 1 } } },
{ $sort: { _id: 1 } }
])- Lookup (join)
db.orders.aggregate([
{ $match: { orgId: 42 } },
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
},
{ $unwind: "$user" }
])- Faceted search
db.products.aggregate([
{ $match: { status: "active" } },
{
$facet: {
stats: [
{
$group: {
_id: null,
avgPrice: { $avg: "$price" },
count: { $sum: 1 }
}
}
],
top: [{ $sort: { sold: -1 } }, { $limit: 10 }]
}
}
])- Window functions
db.sales.aggregate([
{
$setWindowFields: {
partitionBy: "$storeId",
sortBy: { date: 1 },
output: {
rolling7: {
$sum: "$amount",
window: { range: [-6, 0], unit: "day" }
}
}
}
}
])- Atlas Search (if enabled)
db.collection.aggregate([
{
$search: {
index: "default",
text: { query: "exact phrase", path: ["name", "bio"] }
}
},
{ $limit: 10 }
])- out
db.collection.aggregate([
{ $match: { status: "active" } },
{
$merge: {
into: "collection_active",
whenMatched: "replace",
whenNotMatched: "insert"
}
}
])6) Bulk Operations
- Unordered bulk write
db.collection.bulkWrite(
[
{ insertOne: { document: { email: "a@b.com" } } },
{
updateOne: {
filter: { email: "a@b.com" },
update: { $set: { status: "active" } }
}
},
{ deleteOne: { filter: { status: "inactive" } } }
],
{ ordered: false }
)7) Transactions
- Session and transaction (replica set / sharded)
const session = db.getMongo().startSession()
session.startTransaction({ writeConcern: { w: "majority" } })
try {
const users = session.getDatabase("app").getCollection("users")
const wallets = session.getDatabase("app").getCollection("wallets")
users.updateOne({ _id: uid }, { $inc: { credits: -10 } }, { session })
wallets.updateOne({ _id: uid }, { $inc: { balance: 10 } }, { session })
session.commitTransaction()
} catch (e) {
session.abortTransaction()
throw e
} finally {
session.endSession()
}8) Schema Validation
- Create collection with validator (JSON Schema)
db.createCollection("users", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["email", "createdAt"],
properties: {
email: {
bsonType: "string",
pattern: "^[^@\\s]+@[^@\\s]+\\.[^@\\s]+$"
},
createdAt: { bsonType: "date" },
status: { enum: ["active", "pending", "inactive"] }
},
additionalProperties: true
}
},
validationLevel: "moderate", // or "strict"
validationAction: "error" // or "warn"
})- Update validator on existing collection
db.runCommand({
collMod: "users",
validator: { $jsonSchema: { bsonType: "object", required: ["email"] } },
validationLevel: "strict"
})9) Geospatial
- 2dsphere index and near
db.places.createIndex({ location: "2dsphere" })
db.places.find({
location: {
$near: {
$geometry: { type: "Point", coordinates: [4.8952, 52.3702] },
$maxDistance: 2000
}
}
})- Polygon containment
db.places.find({
location: {
$geoWithin: {
$geometry: {
type: "Polygon",
coordinates: [[[x1, y1], [x2, y2], [x3, y3], [x1, y1]]]
}
}
}
})10) Change Streams (real-time)
- Watch changes
const cs = db.collection.watch([{ $match: { "fullDocument.status": "active" } }])
cs.hasNext() && printjson(cs.next())- With resume token
const cs = db.collection.watch()
const first = cs.next()
const resumeToken = cs.getResumeToken()
// later:
db.collection.watch([], { resumeAfter: resumeToken })11) Administrative Operations
- Create/drop collection
db.createCollection("logs")
db.logs.drop()- Drop index
db.collection.dropIndex("idx_email_unique")- Stats
db.collection.stats()
db.stats()- Current operations
db.currentOp()- Kill operation
db.killOp(opid)- Collation (case-insensitive sorts/searches)
db.collection.find({ name: "jo" }).collation({ locale: "en", strength: 2 })
db.collection.createIndex({ name: 1 }, { collation: { locale: "en", strength: 2 } })- MaxTimeMS (protect server)
db.collection.find({}).maxTimeMS(2000)- Read preferences
db.getMongo().setReadPref("secondaryPreferred", [{ tag: "region:europe" }])- Profiling
db.setProfilingLevel(1, { slowms: 100 }) // 0 off, 1 slow, 2 all
db.system.profile.find().sort({ ts: -1 }).limit(5)12) ObjectId and Dates
- Generate ObjectId and extract timestamp
const id = ObjectId()
id.getTimestamp() // Date from ObjectId- ISODate helpers
ISODate("2026-01-01T00:00:00Z")
new Date() // client-local to BSON date13) Driver Tips (Node.js)
- Safe query builder pattern
const filter = { orgId, status: "active" } // whitelist fields
const projection = { name: 1, email: 1 }
const docs = await db.collection("users").find(filter, { projection }).toArray()- Pagination (seek method)
const page = await db.collection("items")
.find({ orgId })
.sort({ createdAt: -1, _id: -1 })
.limit(21)
.toArray()
// Use last doc's (createdAt, _id) as next cursor- Unique per org (compound unique)
db.users.createIndex({ orgId: 1, email: 1 }, { unique: true })14) Injection-aware patterns and safety tips
- Prefer implicit equality for fixed values:
db.collection.find({ email: "a@b.com" })instead of:
db.collection.find({ email: { $eq: "a@b.com" } })-
When accepting user input for keys/filters, validate and whitelist allowed fields and operators. Do not pass raw, user-supplied objects directly to query APIs.
-
For text/regex from users, escape metacharacters or use anchored, bounded patterns. Prefer $regex only when necessary.
-
Use parameterized patterns or builders in drivers (e.g., in Node.js, build objects programmatically rather than JSON.parse of user strings).
-
If you must allow operators, validate against an allowlist such as [āgteā,ālteā,āninā,āneā].
-
In MongoDB Atlas App Services/Realm or MongoDB Enterprise, consider schema validation rules to constrain allowed shapes.
-
Limit result sizes, set timeouts, and use projections to reduce load.
-
For multi-document invariants, use transactions or model patterns that avoid cross-document constraints.
References
I was preparing for the Avans 2.1 Remindo Test