askesis

MongoDB essentials: 50 cards on queries, indexes and aggregation

MongoDB basics: documents and BSON, CRUD in mongosh, query operators, indexes, the aggregation pipeline, embedding vs referencing, replica sets and sharding.

DatabasesBeginner50 cardsFree

Practice now

Study without an account

0 of 50 seen0 graduated
What is a MongoDB document?

Scheduled with the default Askesis timings. Progress is saved in this browser.

All 50 cards

  1. 1
    What is a MongoDB document?
    A record of field–value pairs, like a JSON object, that can nest objects and arrays; it is stored as BSON
  2. 2
    What is BSON?
    Binary JSON: the binary format MongoDB stores documents in. It adds types JSON lacks, like ObjectId, Date, Decimal128, 32- and 64-bit integers and binary data
  3. 3
    Maximum size of a single document
    16 MB. Store larger files with GridFS, and keep documents from growing without limit
  4. 4
    What is special about the _id field?
    It is every document’s primary key: unique in the collection, immutable, automatically indexed, and generated as an ObjectId if you don’t supply one
  5. 5
    What is inside an ObjectId?
    12 bytes: a 4-byte timestamp in seconds, a 5-byte random value and a 3-byte counter, so IDs roughly sort by creation time
    id.getTimestamp() returns the creation date.
  6. 6
    What is a collection?
    A group of documents, similar to a table but with no fixed schema by default; it is created automatically on the first insert
  7. 7
    Enforce a schema on a collection
    js
    db.createCollection('users', {
      validator: {
        $jsonSchema: {
          bsonType: 'object',
          required: ['email'],
          properties: { email: { bsonType: 'string' } },
        },
      },
    })
    Add a validator to an existing collection with collMod.
  8. 8
    Insert one and several documents
    js
    db.users.insertOne({ name: 'Ada', age: 36 })
    db.users.insertMany([{ name: 'Alan' }, { name: 'Grace' }])
  9. 9
    What does this return?
    js
    db.users.find(
      { age: { $gte: 18 } },
      { name: 1, email: 1, _id: 0 },
    )
    The name and email (without _id) of every user aged 18 or over: the first argument filters, the second is a projection
  10. 10
    Can a projection mix 1 and 0?
    No, except for _id: either list the fields to include or the fields to exclude
  11. 11
    What does find() return?
    A cursor that fetches results in batches; iterate it, or call .toArray() in a driver
    mongosh prints the first 20 documents; type it for more.
  12. 12
    What does this return?
    js
    db.posts.find().sort({ createdAt: -1 }).limit(10)
    The ten newest posts: -1 sorts descending, 1 ascending
    Paging with large skip() values gets slow; filter on an indexed field instead, like createdAt < lastSeen.
  13. 13
    Change one field of a document
    js
    db.users.updateOne({ _id: id }, { $set: { email: '[email protected]' } })
  14. 14
    What happens here?
    js
    db.users.updateOne({ _id: id }, { email: '[email protected]' })
    It throws: update documents must use operators like $set. To replace a whole document on purpose, use replaceOne
  15. 15
    Common update operators
    $set sets fields, $unset removes them, $inc adds to a number, $push appends to an array, $addToSet appends only if absent, $pull removes matching elements
  16. 16
    What does upsert: true do?
    Updates the matching document, or inserts a new one built from the filter and the update if nothing matches
    js
    db.stats.updateOne({ day: '2026-10-15' }, { $inc: { views: 1 } }, { upsert: true })
  17. 17
    deleteOne vs deleteMany
    deleteOne removes the first matching document; deleteMany removes all matches, and deleteMany({}) empties the collection
  18. 18
    MongoDB comparison operators
    $eq, $ne, $gt, $gte, $lt, $lte, $in and $nin
    js
    db.orders.find({ status: { $in: ['paid', 'shipped'] } })
  19. 19
    Why does this ignore the lower bound?
    js
    db.users.find({ age: { $gt: 18 }, age: { $lt: 30 } })
    A JavaScript object can’t have two age keys, so the second replaces the first. Combine them: { age: { $gt: 18, $lt: 30 } }
  20. 20
    What does this match?
    js
    db.users.find({ $or: [{ role: 'admin' }, { age: { $gte: 65 } }] })
    Users who are admins or at least 65. Listing several fields in one filter, without $or, means AND
  21. 21
    Query a field inside an embedded document
    Use quoted dot notation: { 'address.city': 'Paris' }
    Without quotes, address.city as a key is a JavaScript syntax error.
  22. 22
    What does { tags: 'mongodb' } match when tags is an array?
    Every document whose tags array contains 'mongodb'
    { tags: ['a', 'b'] } matches only that exact array in that order; use $all for “contains both”.
  23. 23
    Why use $elemMatch?
    To require a single array element to meet every condition. { scores: { $gte: 80, $lt: 90 } } can match with one element ≥ 80 and a different one < 90
    js
    db.students.find({ scores: { $elemMatch: { $gte: 80, $lt: 90 } } })
  24. 24
    What does { phone: null } match?
    Documents where phone is null and documents with no phone field at all; use { phone: { $exists: false } } for missing only
  25. 25
    Which extra documents does { status: { $ne: 'banned' } } return?
    Documents that have no status field at all; $ne and $nin match missing fields too
  26. 26
    countDocuments vs estimatedDocumentCount
    countDocuments(filter) counts matching documents exactly; estimatedDocumentCount() returns the whole collection’s count from metadata, much faster
  27. 27
    Create a unique index on email
    js
    db.users.createIndex({ email: 1 }, { unique: true })
    1 is ascending and -1 descending; direction matters mostly for compound sorts.
  28. 28
    The ESR rule for compound indexes
    Order fields as Equality, then Sort, then Range: fields matched exactly first, sort fields next, range filters like $gt last
  29. 29
    Which queries can use an index on { a: 1, b: 1, c: 1 }?
    Queries on its prefixes: a, a and b, or all three. A query on b or c alone can’t use it efficiently
  30. 30
    What is a multikey index?
    An index on an array field: MongoDB indexes every element automatically. A compound index can include at most one array field per document
  31. 31
    Delete sessions an hour after creation
    js
    db.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 })
    A TTL index needs a date field. A background task removes expired documents about every 60 seconds, so deletion isn’t instant.
  32. 32
    How do you check whether a query uses an index?
    Run .explain('executionStats'): IXSCAN means an index scan, COLLSCAN a full collection scan. Compare totalDocsExamined with nReturned
  33. 33
    What is the aggregation pipeline?
    An array of stages, such as $match, $group, $sort and $project, where each stage transforms the documents and passes them to the next
  34. 34
    Total paid order amounts per customer, largest first
    js
    db.orders.aggregate([
      { $match: { status: 'paid' } },
      { $group: { _id: '$customerId', total: { $sum: '$amount' }, orders: { $sum: 1 } } },
      { $sort: { total: -1 } },
    ])
  35. 35
    Why put $match as early as possible in a pipeline?
    It shrinks the data every later stage processes, and a $match at the start of the pipeline can use indexes
  36. 36
    Join orders with their users
    js
    { $lookup: { from: 'users', localField: 'userId', foreignField: '_id', as: 'user' } }
    $lookup is a left outer join within the same database; user is always an array.
  37. 37
    What does { $unwind: '$tags' } do?
    Outputs one copy of the document per element of tags, with tags set to that element; often used after $lookup
  38. 38
    '$amount' vs 'amount' in an aggregation expression
    '$amount' is a field path that reads each document’s amount; 'amount' is just the literal string
  39. 39
    $project vs $addFields
    $project reshapes documents, keeping only what you list (plus _id); $addFields (alias $set) keeps every field and adds or overwrites some
  40. 40
    $out vs $merge
    Both write pipeline results to a collection and must be the last stage: $out replaces the target collection, $merge inserts or updates into it
  41. 41
    When should you embed related data?
    When it is read together with its parent, belongs to it, and stays small and bounded, like a user’s addresses or an order’s line items
  42. 42
    When should you reference another document instead?
    When the related data is large or unbounded, shared by many documents (many-to-many), or read and updated on its own
  43. 43
    Why are ever-growing arrays an anti-pattern?
    An array that grows without limit, like every comment on a post, slows updates and indexes and eventually hits the 16 MB document limit
  44. 44
    Are MongoDB writes atomic?
    A write to a single document is atomic, including its embedded documents. Multi-document ACID transactions exist (since 4.0) but cost more, so model data to need them rarely
  45. 45
    What is a replica set?
    A group of servers holding the same data: one primary takes writes, secondaries copy its oplog, and if the primary fails the others elect a new one
  46. 46
    Why should a replica set have at least three members?
    Electing a primary needs a majority of voting members. With three, losing one still leaves a majority; with two, losing either leaves no primary
  47. 47
    What is the catch with reading from secondaries?
    Replication is asynchronous, so a read preference like secondaryPreferred can return stale data
  48. 48
    What does write concern w: 'majority' mean?
    The write is acknowledged only after most voting members have it, so it survives a primary failover; it is the default since MongoDB 5.0 in most deployments
  49. 49
    What is sharding?
    Horizontal scaling: a collection is split across shards by a shard key, mongos routers send each query to the right shards, and config servers hold the metadata
    Each shard is itself a replica set.
  50. 50
    What makes a bad shard key?
    A steadily increasing value like a timestamp (with ranged sharding, every insert hits one shard), low cardinality, or a field most queries don’t filter on (scatter-gather queries)
    Hashed sharding spreads monotonically increasing keys across shards.

Frequently asked questions

Which syntax do the examples use?

mongosh, the MongoDB shell, which is JavaScript. The Node.js driver uses the same method names and query documents, so the cards carry over directly.

Should I embed or reference related data?

Embed data that is read with its parent and stays bounded, like an order’s items. Reference data that is large, unbounded or shared, like a user’s orders or many-to-many relations.

Does MongoDB support transactions?

Yes. Single-document writes are always atomic, and multi-document ACID transactions are available on replica sets and sharded clusters, though a good schema needs them rarely.