MEAN MongoDB Schema Design and CRUD Operations — Questions and Answers
Question 1: In MongoDB, which design pattern should you prefer when related data is always accessed together and the 'many' side has a bounded, small number of items?
- Embedding the related documents inside the parent document (Correct answer)
- Always using references with separate collections
- Using a junction collection like a relational join table
- Storing the relationship as a comma-separated string field
Correct answer: Embedding the related documents inside the parent document
Embedding is preferred when data is always read together and the nested array won't grow unboundedly (e.g., a blog post's comments when there are fewer than a few hundred). It avoids extra queries and keeps related data in one atomic document.
Question 2: Which MongoDB update operator increments a numeric field by a specified amount without reading the document first?
- $set
- $inc (Correct answer)
- $push
- $add
Correct answer: $inc
$inc atomically increments (or decrements with a negative value) a numeric field by the specified amount. For example, { $inc: { views: 1 } } adds 1 to the views field. $set replaces a field's value entirely.
Question 3: What does `db.collection.findOneAndUpdate()` return by default?
- The document as it appeared BEFORE the update was applied (Correct answer)
- The document as it appears AFTER the update was applied
- A result object with matchedCount and modifiedCount
- A boolean indicating whether the update succeeded
Correct answer: The document as it appeared BEFORE the update was applied
By default, findOneAndUpdate() returns the original document before the update. To return the updated document, you must pass { returnDocument: 'after' } (or returnNewDocument: true in older drivers) as an option.
Question 4: Which MongoDB CRUD method should you use to insert multiple documents in a single network round-trip?
- insertOne() called in a loop
- insertMany() (Correct answer)
- bulkWrite() with insert operations only
- save() with an array argument
Correct answer: insertMany()
insertMany() accepts an array of documents and inserts them all in one operation, drastically reducing network overhead compared to calling insertOne() repeatedly. bulkWrite() also works but is more complex and designed for mixed operation types.
Question 5: In a Mongoose schema, what is the purpose of setting `{ timestamps: true }` as a schema option?
- It automatically adds and manages `createdAt` and `updatedAt` fields on each document (Correct answer)
- It validates that all Date fields contain valid timestamps
- It enables time-to-live (TTL) expiry on the collection
- It logs all write operations with timestamps to the console
Correct answer: It automatically adds and manages `createdAt` and `updatedAt` fields on each document
When timestamps: true is set in a Mongoose schema, Mongoose automatically adds createdAt (set once on insert) and updatedAt (updated on every save/update) fields to every document, handling the bookkeeping automatically.
Question 6: What is the difference between MongoDB's `deleteOne()` and `findOneAndDelete()` methods?
- deleteOne() returns a result with deletedCount; findOneAndDelete() returns the deleted document itself (Correct answer)
- findOneAndDelete() is faster because it skips index lookups
- deleteOne() removes all matching documents; findOneAndDelete() removes only the first
- There is no functional difference; they are aliases
Correct answer: deleteOne() returns a result with deletedCount; findOneAndDelete() returns the deleted document itself
deleteOne() returns an acknowledgment object (e.g., { acknowledged: true, deletedCount: 1 }) but not the document. findOneAndDelete() atomically finds, returns, and deletes the document — useful when you need the document's content after removing it.
In MongoDB, which design pattern should you prefer when related data is always accessed together and the 'many' side has a bounded, small number of items?