Tutorials Logic, IN info@tutorialslogic.com
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Website Development
Practice
Quiz Challenge Interview Questions Certification Practice
Tools
Online Compiler JSON Formatter Regex Tester CSS Unit Converter Color Picker
Compiler Tools
MongoDB

Top 50 MongoDB Interview Questions

Curated questions covering CRUD operations, aggregation pipeline, indexing, replication, sharding, transactions, and Mongoose ODM.

01

What is MongoDB and how does it differ from relational databases?

MongoDB is a NoSQL document database that stores data as BSON (Binary JSON) documents. Differences from RDBMS: no fixed schema (flexible documents), no JOINs (embed or reference), horizontal scaling via sharding, no ACID transactions by default (added in v4.0), and collections instead of tables.

02

What is the difference between SQL and MongoDB terminology?

  • Database = Database
  • Table = Collection
  • Row = Document
  • Column = Field
  • Primary Key = _id field
  • JOIN = $lookup (aggregation) or embedding
  • Index = Index
03

What is a BSON document?

BSON (Binary JSON) is the binary-encoded serialization format MongoDB uses to store documents. It extends JSON with additional types: Date, ObjectId, Binary, Decimal128, and more. BSON is more efficient to parse than JSON and supports richer data types.

Example
{\n  "_id": ObjectId("507f1f77bcf86cd799439011"),\n  "name": "Alice",\n  "age": 30,\n  "createdAt": ISODate("2024-01-01"),\n  "scores": [95, 87, 92],\n  "address": { "city": "NYC", "zip": "10001" }\n}
04

What is the difference between embedding and referencing documents?

  • Embedding - store related data in the same document. Faster reads (single query). Best for one-to-few relationships and data accessed together.
  • Referencing - store related data in separate documents with an _id reference. Better for one-to-many and many-to-many. Avoids document size limit (16MB).
  • Rule of thumb: embed for data you always access together; reference for large or frequently updated sub-documents.
Example
// Embedding\n{ name: "Alice", address: { city: "NYC", zip: "10001" } }\n\n// Referencing\n{ name: "Alice", addressId: ObjectId("...") }
05

What are the basic CRUD operations in MongoDB?

  • Create: insertOne(), insertMany()
  • Read: findOne(), find(), with filters and projections
  • Update: updateOne(), updateMany(), replaceOne() with $set, $inc, $push operators
  • Delete: deleteOne(), deleteMany()
Example
db.users.insertOne({ name: "Alice", age: 30 });\ndb.users.find({ age: { $gt: 25 } }, { name: 1, _id: 0 });\ndb.users.updateOne({ name: "Alice" }, { $set: { age: 31 } });\ndb.users.deleteOne({ name: "Alice" });
06

What is the difference between find() and findOne()?

  • find() - returns a cursor to all matching documents. Iterate with forEach() or toArray().
  • findOne() - returns the first matching document directly (not a cursor). Returns null if not found.
Example
db.users.findOne({ email: "alice@example.com" }); // single doc or null\ndb.users.find({ age: { $gte: 18 } }).limit(10);   // cursor
07

What are MongoDB query operators?

  • Comparison: $eq, $ne, $gt, $gte, $lt, $lte, $in, $nin
  • Logical: $and, $or, $not, $nor
  • Element: $exists, $type
  • Array: $all, $elemMatch, $size
  • Evaluation: $regex, $where, $expr
Example
db.products.find({\n  price: { $gte: 10, $lte: 100 },\n  category: { $in: ["electronics", "books"] },\n  tags: { $all: ["sale", "new"] }\n});
08

What is the aggregation pipeline?

The aggregation pipeline processes documents through a sequence of stages, each transforming the data. Common stages: $match, $group, $project, $sort, $limit, $skip, $lookup, $unwind, $addFields, $count.

Example
db.orders.aggregate([\n  { $match: { status: "completed" } },\n  { $group: { _id: "$customerId", total: { $sum: "$amount" } } },\n  { $sort: { total: -1 } },\n  { $limit: 10 }\n]);
09

What is the difference between $match and find()?

  • find() - standalone query operation. Returns documents directly.
  • $match - aggregation pipeline stage. Filters documents within a pipeline. Should be placed early in the pipeline to reduce documents processed by subsequent stages.
  • $match uses the same query syntax as find().
10

What is the $lookup stage?

$lookup performs a left outer join between two collections, similar to SQL JOIN. It adds an array field to each document with matching documents from the joined collection.

Example
db.orders.aggregate([\n  {\n    $lookup: {\n      from: "customers",\n      localField: "customerId",\n      foreignField: "_id",\n      as: "customer"\n    }\n  },\n  { $unwind: "$customer" }\n]);
11

What is the $unwind stage?

$unwind deconstructs an array field, outputting one document per array element. Used before $group or $lookup when working with array fields.

Example
// Document: { name: "Alice", scores: [90, 85, 92] }\ndb.students.aggregate([\n  { $unwind: "$scores" }\n]);\n// Outputs 3 documents:\n// { name: "Alice", scores: 90 }\n// { name: "Alice", scores: 85 }\n// { name: "Alice", scores: 92 }
12

What is the difference between $group accumulators $sum, $avg, $min, $max, $push, $addToSet?

  • $sum - sums numeric values. $sum: 1 counts documents.
  • $avg - calculates average.
  • $min / $max - finds minimum/maximum value.
  • $push - creates an array of all values (allows duplicates).
  • $addToSet - creates an array of unique values.
Example
db.sales.aggregate([{\n  $group: {\n    _id: "$category",\n    count: { $sum: 1 },\n    avgPrice: { $avg: "$price" },\n    allTags: { $push: "$tag" },\n    uniqueTags: { $addToSet: "$tag" }\n  }\n}]);
13

What are MongoDB indexes and why are they important?

Indexes improve query performance by allowing MongoDB to find documents without scanning the entire collection. Without an index, MongoDB performs a collection scan (COLLSCAN). With an index, it performs an index scan (IXSCAN).

Example
db.users.createIndex({ email: 1 });           // ascending\ndb.users.createIndex({ age: -1 });            // descending\ndb.users.createIndex({ email: 1 }, { unique: true }); // unique\ndb.users.getIndexes();                        // list indexes\ndb.users.find({ email: "a@b.com" }).explain("executionStats");
14

What is the difference between single field, compound, and multikey indexes?

  • Single field index - index on one field. Most common.
  • Compound index - index on multiple fields. Order matters. Supports queries on the prefix fields.
  • Multikey index - automatically created when indexing an array field. One index entry per array element.
  • Text index - for full-text search. Sparse index - only indexes documents that have the field.
Example
db.users.createIndex({ lastName: 1, firstName: 1 }); // compound\ndb.products.createIndex({ tags: 1 }); // multikey (tags is array)\ndb.articles.createIndex({ content: "text" }); // text index
15

What is the difference between $set and $unset update operators?

  • $set - sets the value of a field. Creates the field if it does not exist.
  • $unset - removes a field from a document.
  • Other update operators: $inc (increment), $push (add to array), $pull (remove from array), $addToSet (add unique to array), $pop (remove first/last array element).
Example
db.users.updateOne({ _id: id }, {\n  $set: { age: 31, "address.city": "LA" },\n  $unset: { tempField: "" },\n  $inc: { loginCount: 1 },\n  $push: { tags: "premium" }\n});
16

What is the difference between updateOne and replaceOne?

  • updateOne with $set - modifies specific fields. Other fields are preserved.
  • replaceOne - replaces the entire document (except _id). All fields not in the replacement are removed.
Example
// updateOne - only changes age\ndb.users.updateOne({ _id: id }, { $set: { age: 31 } });\n\n// replaceOne - entire document replaced\ndb.users.replaceOne({ _id: id }, { name: "Alice", age: 31 });
17

What is the difference between deleteOne and deleteMany?

  • deleteOne - deletes the first document matching the filter.
  • deleteMany - deletes all documents matching the filter.
  • deleteMany({}) - deletes all documents in the collection (use with caution).
18

What is the difference between drop() and deleteMany({})?

  • deleteMany({}) - removes all documents but keeps the collection, indexes, and metadata.
  • drop() - removes the entire collection including all documents, indexes, and metadata. Faster for clearing large collections.
19

What are MongoDB transactions?

MongoDB 4.0+ supports multi-document ACID transactions. Use sessions to group operations. Transactions work across multiple documents and collections.

Example
const session = client.startSession();\ntry {\n  session.startTransaction();\n  await db.accounts.updateOne(\n    { _id: fromId }, { $inc: { balance: -100 } }, { session }\n  );\n  await db.accounts.updateOne(\n    { _id: toId }, { $inc: { balance: 100 } }, { session }\n  );\n  await session.commitTransaction();\n} catch (e) {\n  await session.abortTransaction();\n} finally {\n  session.endSession();\n}
20

What is the difference between replica set and sharding?

  • Replica set - multiple copies of the same data for high availability and read scaling. One primary (writes) and multiple secondaries (reads/failover).
  • Sharding - distributes data across multiple servers (shards) for horizontal scaling of large datasets. Each shard holds a subset of the data.
21

What is a replica set in MongoDB?

A replica set is a group of MongoDB instances that maintain the same dataset. It provides redundancy and high availability. The primary receives all writes; secondaries replicate from the primary. If the primary fails, an election promotes a secondary.

22

What is the difference between $project and $addFields?

  • $project - reshapes documents. Can include/exclude fields and add computed fields. Fields not mentioned are excluded (unless _id).
  • $addFields - only adds new fields or overwrites existing ones. All existing fields are preserved.
Example
// $project - only name and computed fullName\n{ $project: { name: 1, fullName: { $concat: ["$first", " ", "$last"] } } }\n\n// $addFields - adds fullName, keeps all other fields\n{ $addFields: { fullName: { $concat: ["$first", " ", "$last"] } } }
23

What is the difference between $facet and multiple aggregation pipelines?

$facet runs multiple sub-pipelines on the same input documents simultaneously, returning results in a single document. Useful for faceted search (multiple categorizations at once).

Example
db.products.aggregate([{\n  $facet: {\n    byCategory: [{ $group: { _id: "$category", count: { $sum: 1 } } }],\n    byPrice: [{ $bucket: { groupBy: "$price", boundaries: [0,50,100,500] } }],\n    total: [{ $count: "count" }]\n  }\n}]);
24

What is the difference between $count stage and $group with $sum: 1?

  • { $count: "total" } - shorthand for counting documents. Returns { total: N }.
  • { $group: { _id: null, total: { $sum: 1 } } } - more flexible, can be combined with other accumulators.
Example
// Simple count\ndb.users.aggregate([{ $match: { active: true } }, { $count: "activeUsers" }]);\n\n// Count with other stats\ndb.users.aggregate([{ $group: { _id: null, count: { $sum: 1 }, avgAge: { $avg: "$age" } } }]);
25

What is the difference between find() with sort/limit and aggregation with $sort/$limit?

  • find().sort().limit() - simpler syntax for basic queries. Optimized by MongoDB.
  • Aggregation $sort/$limit - part of a pipeline. Required when sorting/limiting after $group or $lookup.
  • Both use indexes when possible. Aggregation is more powerful for complex transformations.
26

What is the difference between ObjectId and UUID as _id?

  • ObjectId (default) - 12-byte BSON type. Encodes timestamp, machine ID, process ID, and counter. Sortable by creation time. Compact.
  • UUID - 16-byte universally unique identifier. Better for distributed systems where multiple services generate IDs. Not sortable by time.
Example
// ObjectId\nconst id = new ObjectId();\nconsole.log(id.getTimestamp()); // creation time\n\n// Custom _id\ndb.users.insertOne({ _id: "custom-id-123", name: "Alice" });
27

What is the difference between $in and $or for multiple value matching?

  • $in: [v1, v2, v3] - checks if a single field matches any value in the array. More efficient, uses index.
  • $or: [{f1:v1}, {f2:v2}] - checks multiple conditions across different fields. Less efficient for same-field checks.
Example
// Prefer $in for same field\ndb.users.find({ status: { $in: ["active", "pending"] } });\n\n// Use $or for different fields\ndb.users.find({ $or: [{ email: "a@b.com" }, { phone: "123" }] });
28

What is the difference between sparse and partial indexes?

  • Sparse index - only indexes documents that have the indexed field. Smaller index size. Cannot enforce uniqueness across documents missing the field.
  • Partial index - indexes only documents matching a filter expression. More flexible than sparse.
Example
// Sparse index\ndb.users.createIndex({ phone: 1 }, { sparse: true });\n\n// Partial index\ndb.users.createIndex({ email: 1 }, {\n  partialFilterExpression: { status: "active" }\n});
29

What is the difference between $regex and text search?

  • $regex - pattern matching on a single field. Can use indexes only for prefix patterns (anchored with ^). Slow for full-text search.
  • Text search ($text with text index) - full-text search across multiple fields. Supports stemming, stop words, and relevance scoring.
Example
// Regex (slow for non-prefix)\ndb.articles.find({ title: { $regex: /mongodb/i } });\n\n// Text search (fast with text index)\ndb.articles.createIndex({ title: "text", body: "text" });\ndb.articles.find({ $text: { $search: "mongodb aggregation" } });
30

What is Mongoose and what does it add over the native MongoDB driver?

Mongoose is an ODM (Object Document Mapper) for MongoDB in Node.js. It adds: schema definition with validation, middleware (pre/post hooks), virtuals, population (reference resolution), query building, and TypeScript support.

Example
const userSchema = new Schema({\n  email: { type: String, required: true, unique: true },\n  age: { type: Number, min: 0, max: 150 }\n});\nuserSchema.pre("save", async function() {\n  this.password = await bcrypt.hash(this.password, 10);\n});\nconst User = model("User", userSchema);
31

What is the difference between Mongoose populate and $lookup?

  • populate() - Mongoose method that resolves references by making additional queries. Simple syntax but N+1 queries.
  • $lookup - MongoDB aggregation stage. Single query with a join. More efficient for large datasets.
Example
// Mongoose populate (multiple queries)\nconst order = await Order.findById(id).populate("customer");\n\n// $lookup (single query)\ndb.orders.aggregate([{ $lookup: { from: "customers", localField: "customerId", foreignField: "_id", as: "customer" } }]);
32

What is the difference between MongoDB Atlas and self-hosted MongoDB?

  • MongoDB Atlas - fully managed cloud service. Automatic backups, scaling, monitoring, and security. Available on AWS, GCP, Azure.
  • Self-hosted - full control over configuration. More complex to manage. Better for specific compliance requirements or cost optimization at scale.
33

What is the difference between $bucket and $bucketAuto?

  • $bucket - groups documents into user-defined ranges (boundaries). You specify the exact boundary values.
  • $bucketAuto - automatically determines boundaries to distribute documents evenly into N buckets.
Example
// $bucket - manual boundaries\n{ $bucket: { groupBy: "$price", boundaries: [0, 25, 50, 100, 500], default: "Other" } }\n\n// $bucketAuto - automatic\n{ $bucketAuto: { groupBy: "$price", buckets: 4 } }
34

What is the difference between $merge and $out in aggregation?

  • $out - writes aggregation results to a new collection. Replaces the collection if it exists.
  • $merge (MongoDB 4.2+) - merges results into an existing collection. Supports insert, replace, merge, keepExisting, and fail modes.
Example
// $out - replaces collection\n{ $out: "monthly_summary" }\n\n// $merge - upsert into existing\n{ $merge: { into: "monthly_summary", on: "_id", whenMatched: "merge", whenNotMatched: "insert" } }
35

What is the difference between findOneAndUpdate and updateOne?

  • updateOne - updates the document and returns the update result (matchedCount, modifiedCount). Does not return the document.
  • findOneAndUpdate - updates the document and returns the document (before or after update based on returnDocument option).
Example
// Returns update result, not the document\nawait db.users.updateOne({ _id: id }, { $set: { age: 31 } });\n\n// Returns the updated document\nconst updated = await db.users.findOneAndUpdate(\n  { _id: id },\n  { $set: { age: 31 } },\n  { returnDocument: "after" }\n);
36

What is the difference between $push and $addToSet?

  • $push - adds an element to an array. Allows duplicates.
  • $addToSet - adds an element to an array only if it does not already exist. Prevents duplicates.
Example
db.users.updateOne({ _id: id }, { $push: { tags: "premium" } });    // allows duplicates\ndb.users.updateOne({ _id: id }, { $addToSet: { tags: "premium" } }); // unique only
37

What is the difference between $pull and $pop?

  • $pull - removes all elements from an array that match a condition.
  • $pop: 1 - removes the last element. $pop: -1 - removes the first element.
Example
db.users.updateOne({ _id: id }, { $pull: { tags: "expired" } }); // remove by value\ndb.users.updateOne({ _id: id }, { $pop: { scores: 1 } });         // remove last\ndb.users.updateOne({ _id: id }, { $pop: { scores: -1 } });        // remove first
38

What is the difference between countDocuments and estimatedDocumentCount?

  • countDocuments(filter) - counts documents matching a filter. Accurate. Performs a collection scan or index scan.
  • estimatedDocumentCount() - uses collection metadata for a fast estimate. No filter support. Very fast but may be slightly inaccurate.
Example
await db.users.countDocuments({ active: true });  // accurate, with filter\nawait db.users.estimatedDocumentCount();           // fast estimate, no filter
39

What is the difference between $expr and regular query operators?

$expr allows using aggregation expressions within a query filter. It enables comparing fields within the same document, which regular operators cannot do.

Example
// Compare two fields in the same document\ndb.orders.find({\n  $expr: { $gt: ["$totalAmount", "$discountAmount"] }\n});\n\n// Cannot do this with regular operators\n// db.orders.find({ totalAmount: { $gt: "$discountAmount" } }) // WRONG
40

What is the difference between MongoDB change streams and polling?

  • Polling - repeatedly querying for changes. Inefficient, adds load, introduces latency.
  • Change streams - real-time notifications of data changes using the oplog. Efficient push-based model. Requires replica set or sharded cluster.
Example
const changeStream = db.collection("orders").watch();\nchangeStream.on("change", (change) => {\n  console.log("Change detected:", change.operationType);\n});
41

What is the difference between $graphLookup and $lookup?

  • $lookup - single-level join between two collections.
  • $graphLookup - recursive lookup for graph/tree data structures. Traverses a collection recursively following references.
Example
// Find all ancestors of an employee\ndb.employees.aggregate([{\n  $graphLookup: {\n    from: "employees",\n    startWith: "$managerId",\n    connectFromField: "managerId",\n    connectToField: "_id",\n    as: "reportingHierarchy"\n  }\n}]);
42

What is the difference between MongoDB Atlas Search and $regex?

  • $regex - basic pattern matching. Limited full-text capabilities. Slow without prefix anchoring.
  • Atlas Search - built on Apache Lucene. Supports fuzzy matching, autocomplete, synonyms, relevance scoring, and faceted search. Requires Atlas.
43

What is the difference between $setWindowFields and $group?

  • $group - collapses documents into groups. Individual documents are lost.
  • $setWindowFields (MongoDB 5.0+) - computes window functions (running totals, rankings, moving averages) while preserving individual documents.
Example
db.sales.aggregate([{\n  $setWindowFields: {\n    partitionBy: "$category",\n    sortBy: { date: 1 },\n    output: {\n      runningTotal: { $sum: "$amount", window: { documents: ["unbounded", "current"] } }\n    }\n  }\n}]);
44

What is the difference between MongoDB 4.x and 5.x+ features?

  • MongoDB 4.0 - multi-document ACID transactions.
  • MongoDB 4.2 - distributed transactions across shards, $merge aggregation stage.
  • MongoDB 4.4 - $unionWith, $accumulator, $function aggregation operators.
  • MongoDB 5.0 - time series collections, $setWindowFields, versioned API.
  • MongoDB 6.0 - encrypted fields, $densify, $fill aggregation stages.
  • MongoDB 7.0 - compound wildcard indexes, Atlas Stream Processing.
45

What is the difference between time series collections and regular collections?

Time series collections (MongoDB 5.0+) are optimized for storing time-stamped data (IoT, metrics, logs). They automatically compress data, improve query performance for time-range queries, and support automatic expiration via TTL.

Example
db.createCollection("sensorData", {\n  timeseries: {\n    timeField: "timestamp",\n    metaField: "sensorId",\n    granularity: "seconds"\n  },\n  expireAfterSeconds: 86400 // auto-delete after 1 day\n});
46

What is the difference between $sample and $limit for random documents?

  • $limit - returns the first N documents in the current order. Deterministic.
  • $sample - returns N randomly selected documents. Uses a random cursor or collection scan depending on size.
Example
db.users.aggregate([{ $sample: { size: 5 } }]); // 5 random documents
47

What is the difference between upsert and insert in MongoDB?

  • insert - always creates a new document. Fails if _id already exists.
  • upsert (update with upsert: true) - updates if document exists, inserts if not. Atomic operation.
Example
db.users.updateOne(\n  { email: "alice@example.com" },\n  { $set: { name: "Alice", lastLogin: new Date() } },\n  { upsert: true }  // insert if not found\n);
48

What is the difference between MongoDB explain() modes?

  • queryPlanner (default) - shows the winning plan without executing.
  • executionStats - executes the query and shows performance stats (nReturned, totalDocsExamined, executionTimeMillis).
  • allPlansExecution - shows stats for all candidate plans.
Example
db.users.find({ age: { $gt: 25 } }).explain("executionStats");\n// Check: totalDocsExamined vs nReturned\n// Good: IXSCAN (index scan)\n// Bad: COLLSCAN (collection scan)
49

What is the difference between $cond and $switch in aggregation?

  • $cond - ternary operator: { $cond: { if: condition, then: value, else: value } }
  • $switch - multi-branch conditional, like a switch statement. Cleaner for multiple conditions.
Example
// $cond\n{ $cond: { if: { $gte: ["$score", 90] }, then: "A", else: "B" } }\n\n// $switch\n{ $switch: { branches: [\n  { case: { $gte: ["$score", 90] }, then: "A" },\n  { case: { $gte: ["$score", 80] }, then: "B" }\n], default: "C" } }
50

What is the difference between MongoDB TTL index and manual deletion?

  • TTL index - automatically deletes documents after a specified time. Background process runs every 60 seconds. Set on a Date field.
  • Manual deletion - requires application code to query and delete expired documents. More control but more complexity.
Example
// Auto-delete sessions after 1 hour\ndb.sessions.createIndex({ createdAt: 1 }, { expireAfterSeconds: 3600 });

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.