70 Progressive Questions (Easy to Advanced + Scenarios)
70 comprehensive interview questions spanning database basics, Mongoose ODM abstractions, advanced aggregation pipelines, system architecture, performance tuning, and real-world scenario challenges.
Q21: What is the MongoDB Aggregation Framework and how does it work?
The Aggregation Framework is a data processing pipeline model. Documents enter a multi-stage pipeline that transforms, filters, groups, sorts, and reshapes them into aggregated results. Each stage passes its calculated output directly to the next stage.
- Multi-stage transformation pipeline.
- Executes native database analytics bypassing application memory processing.
How do aggregation stages pass data forward down the pipeline?
Q22: Explain $match, $group, and $project pipeline stages.
$match: Filters documents to allow only those matching specified conditions to pass (place$matchfirst to leverage indexes).$group: Groups input documents by a specified_idexpression and applies accumulator operators ($sum,$avg,$push).$project: Reshapes documents by adding, removing, or renaming fields.
db.orders.aggregate([
{ $match: { status: 'completed' } }, // 1. Filter
{ $group: {
_id: '$customerId',
totalSpent: { $sum: '$amount' }, // 2. Group & Sum
orderCount: { $sum: 1 }
}},
{ $sort: { totalSpent: -1 } } // 3. Sort
]);- Place
$matchas early as possible to reduce document volume. $groupperforms SQLGROUP BYaggregations.
Why should $match stages be placed at the very beginning of an aggregation pipeline?
Q23: How does the $lookup stage perform left outer joins between collections?
The $lookup stage performs a left outer join to pull documents from another collection into an array field:
from: Target collection name.localField: Key field in current collection.foreignField: Key field in target collection.as: Output array field name.
- Performs left outer joins between collections.
- Outputs matching joined documents into an array field.
What data type does the $lookup stage produce for the joined output 'as' field?
Q24: What does the $unwind stage do in an aggregation pipeline?
The $unwind stage deconstructs an array field from input documents to output a document for each element of the array. Each output document replaces the array with an individual element item. Commonly paired with $lookup to flatten joined arrays.
- Deconstructs array fields into individual document streams.
- Use
preserveNullAndEmptyArrays: trueto keep documents missing the array.
If a document contains an array of 3 items, how many output documents will $unwind produce for that document?
Q25: What are $facet and $bucket stages used for?
$facet: Executes multiple aggregation sub-pipelines concurrently within a single stage on the same input documents (useful for multi-faceted search and dashboard filtering).$bucket: Categorizes incoming documents into groups (buckets) based on specified boundaries and criteria.
$facetpowers multi-faceted search breakdowns in a single query.$bucketcategorizes numbers into defined numerical range groups.
Which stage allows running parallel aggregation pipelines to compute search results and category totals in one query pass?
Q26: What is the purpose of $addFields (or $set) in aggregation?
The $addFields stage adds new computed fields or modifies existing fields in passing documents without removing un-mentioned existing fields (unlike $project, which excludes un-specified fields unless explicitly preserved).
- Adds or overrides specific document fields.
- Preserves all existing document keys automatically.
How does $addFields differ from $project in aggregation?
Q27: What is the RAM limit for an aggregation stage, and how do you bypass it?
Pipeline stages have a default memory limit of 100 Megabytes of RAM. If a stage (like $sort or $group) exceeds 100MB, MongoDB throws an error. To bypass this, pass { allowDiskUse: true }, allowing pipeline stages to spill temporary data to disk files.
- Default aggregation stage RAM ceiling: 100MB.
- Use
{ allowDiskUse: true }to write intermediate data to temporary disk space.
Which query option allows aggregation stages to exceed the 100MB RAM processing limit?
Q28: How does Mongoose .populate() work, and what are its performance trade-offs?
populate() automates replacing specified document path references (ObjectId) with actual documents from another collection. Trade-off: Under the hood, populate() executes separate additional queries in application code (not a native database engine join), which can lead to $N+1$ query performance issues if misused.
const post = await Post.findById(postId)
.populate('author', 'name email') // Replace author ObjectId with name and email
.exec();- Fills referenced ObjectIds with full document objects.
- Executes secondary queries under the hood; use
$lookupfor complex native joins.
Does Mongoose .populate() execute a native database join inside MongoDB engine memory?
Q29: What is the .lean() method in Mongoose, and why does it boost read performance?
By default, Mongoose query results return heavy Mongoose Document instances complete with internal state, getters/setters, change tracking, and method bindings. Chaining .lean() tells Mongoose to skip document hydration and return plain JavaScript objects (POJOs), making reads up to 5x faster.
- Returns plain JavaScript objects instead of heavy Mongoose Document instances.
- Drastically reduces CPU and memory overhead for read-heavy APIs.
What capability do you lose when executing a query with .lean() in Mongoose?
Q30: Does MongoDB support ACID Transactions? How do multi-document transactions work?
Yes, MongoDB supports full multi-document ACID transactions (starting in version 4.0 for Replica Sets and 4.2 for Sharded Clusters). Transactions allow executing multiple read/write operations atomically using a session (session.startTransaction()). If an operation fails, calling abortTransaction() rolls back all updates.
const session = await mongoose.startSession();
session.startTransaction();
try {
await Account.updateOne({ _id: fromId }, { $inc: { balance: -100 } }, { session });
await Account.updateOne({ _id: toId }, { $inc: { balance: 100 } }, { session });
await session.commitTransaction();
} catch (err) {
await session.abortTransaction();
} finally {
session.endSession();
}- Multi-document ACID transactions require Replica Sets or Sharded Clusters.
- Managed via Client Sessions (
session.commitTransaction()).
Which deployment architecture is required to run multi-document ACID transactions in MongoDB?