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 date

13) 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