Питання та відповіді для співбесіди щодо агрегації в MongoDB

Основні питання щодо агрегації

Питання 1: Що таке Фреймворк Агрегації (Aggregation Framework) у MongoDB?

Відповідь:
Фреймворк Агрегації — це потужний інструмент для обробки та трансформації даних у MongoDB.
Він працює як конвеєр, де кожен етап обробляє документи та передає результати на наступний етап.

Q2: Які основні етапи конвеєра агрегації?

Відповідь:
Основні етапи включають:

  • $match: Фільтрує документи (аналогічно до find()).
  • $group: Групує документи за певним полем і виконує обчислення (наприклад, sum, avg).
  • $project: Переформатовує документи, включаючи або виключаючи конкретні поля.
  • $sort: Сортує документи у порядку зростання або спадання.
  • $limit: Обмежує кількість документів.
  • $skip: Пропускає певну кількість документів.
  • $unwind: Розділяє масиви (array) на окремі документи.

Q3: Як працює етап $match?

Відповідь:
Етап $match фільтрує документи на основі конкретних умов, подібно до методу find().

Приклад:

db.orders.aggregate([  
{ $match: { status: "completed" } }  
])

Це вибирає тільки ті документи, де поле status має значення “completed”.

Q4: Як використовувати етап $project в агрегації?

Відповідь:
Етап $project переформатовує документи, включаючи, виключаючи або змінюючи поля.

Приклад:

db.orders.aggregate([  
{ $project: { _id: 0, orderId: 1, amount: 1, discount: { $multiply: ["$amount", 0.1] } } }  
])

Це вибирає тільки поля orderId, amount і обчислюване поле discount, виключаючи поле _id.

Q5: Поясніть етап $group з прикладом.

Відповідь:
Етап $group групує документи за певним полем і застосовує агрегаційні функції, такі як $sum, $avg, $min, $max тощо.

Приклад:

db.orders.aggregate([  
{ $group: { _id: "$status", totalAmount: { $sum: "$amount" }, count: { $sum: 1 } } }  
])

Це групує замовлення за статусом і обчислює загальну суму та кількість для кожного статусу.

Q6: Як працює етап $unwind у MongoDB?

Відповідь:
Етап $unwind розділяє поле масиву (array) у документі на кілька документів, кожен з яких містить один елемент масиву.

Приклад:

db.orders.aggregate([  
{ $unwind: "$items" },  
{ $project: { orderId: 1, item: "$items.name", quantity: "$items.quantity" } }  
])

Якщо документ містить масив items, цей запит створить окремі документи для кожного елемента масиву.

Q7: Як можна поєднати етапи $match і $group?

Відповідь:
Ви можете використовувати $match для попереднього фільтрування документів, а потім застосовувати $group для виконання агрегацій над відфільтрованими результатами.

Приклад:

db.orders.aggregate([  
{ $match: { status: "completed" } },  
{ $group: { _id: "$customerId", totalSpent: { $sum: "$amount" } } }  
])

Це обчислює загальну суму, витрачену кожним клієнтом, чиї замовлення позначені як “completed”.

Q8: Що таке $lookup у MongoDB, і як його використовувати?

Відповідь:
Етап $lookup виконує об’єднання (join) між двома колекціями.

Приклад:

db.orders.aggregate([  
{  
$lookup: {  
from: "customers", // Цільова колекція  
localField: "customerId", // Поле в 'orders'  
foreignField: "_id", // Поле в 'customers'  
as: "customerDetails" // Результуюче поле  
}  
}  
])

Цей запит об’єднує колекцію orders із колекцією customers, додаючи відповідні деталі клієнтів у поле customerDetails.

Q9: Поясніть етап $bucket з прикладом.

Відповідь:
Етап $bucket групує документи у сегменти (buckets) на основі заданого діапазону.

Приклад:

db.orders.aggregate([  
{  
$bucket: {  
groupBy: "$amount", // Поле для групування  
boundaries: [0, 50, 100, 200], // Межі сегментів  
default: "Other", // Сегмент для значень поза межами  
output: { count: { $sum: 1 }, totalAmount: { $sum: "$amount" } }  
}  
}  
])

Це групує замовлення у сегменти залежно від їх суми.

Q10: Що таке $facet і як ним користуватися?

Відповідь:
Етап $facet дозволяє виконувати кілька агрегацій на одному наборі даних та повертати кілька результатів у межах одного запиту.

Приклад:

db.orders.aggregate([  
{  
$facet: {  
"totalOrders": [{ $count: "count" }],
"completedOrders": [{ $match: { status: "completed" } }, { $count: "count" }],  
"averageAmount": [{ $group: { _id: null, avgAmount: { $avg: "$amount" } } }]  
}  
}  
])

Цей запит надає загальну кількість замовлень, кількість завершених замовлень і середню суму замовлення.

Розширені питання щодо агрегації

Q11: Як можна використовувати етап $merge у конвеєрі агрегації?

Відповідь:
Етап $merge записує результат агрегаційного конвеєра у вказану колекцію.

Приклад:

db.orders.aggregate([  
{ $group: { _id: "$status", totalAmount: { $sum: "$amount" } } },  
{ $merge: { into: "orderSummary", whenMatched: "merge", whenNotMatched: "insert" } }  
])

Це групує замовлення за статусом і зберігає результат у колекції orderSummary.

Q12: Що таке $out у агрегації MongoDB?

Відповідь:
Етап $out записує результати агрегаційного конвеєра в нову колекцію, замінюючи її вміст.

Приклад:

db.orders.aggregate([  
{ $group: { _id: "$customerId", totalSpent: { $sum: "$amount" } } },  
{ $out: "customerTotals" }  
])

Це зберігає загальну суму витрат кожного клієнта у колекцію customerTotals.

Q13: Напишіть запит для обчислення середньої суми замовлення для кожного клієнта і сортування за середньою сумою у порядку спадання.

Відповідь:

db.orders.aggregate([  
{ $group: { _id: "$customerId", avgAmount: { $avg: "$amount" } } },  
{ $sort: { avgAmount: -1 } }  
])

Q14: Як можна розгортати вкладені масиви (arrays) за допомогою агрегації?

Відповідь:
Ви можете використовувати $unwind для розгортання вкладених масивів.

Приклад:

db.products.aggregate([  
{ $unwind: "$categories" },  
{ $group: { _id: "$categories", productCount: { $sum: 1 } } }  
])

Q15: Напишіть запит, щоб знайти трьох найкращих клієнтів, які витратили найбільше.

Відповідь:

db.orders.aggregate([  
{ $group: { _id: "$customerId", totalSpent: { $sum: "$amount" } } },  
{ $sort: { totalSpent: -1 } },  
{ $limit: 3 }  
])

Ці питання та приклади мають допомогти вам ефективно підготуватися до питань на співбесіді, пов’язаних із агрегацією.

Перекладено з: MongoDB Aggregation Interview Questions and Answers

Leave a Reply

Your email address will not be published. Required fields are marked *