← К оглавлению занятия
⚡ Кратко: суть занятия
Summary session 19 повторяет практические стадии aggregation pipeline.
$bucket раскладывает документы по диапазонам, например цену жилья в Барселоне.
$match фильтрует документы, $project выбирает поля, $unwind разворачивает массив reviews.
$set добавляет поля, $unset удаляет лишнее, $out записывает новую коллекцию.
Практические задачи повторяют reviews, average score, total в sales, активного reviewer, популярные cuisines, $lookup и Brighton Beach.
Закрепляющий тест спрашивает use, find, выборку по _id и skip(5).
Разбор ДЗ 19 работает с ich.Spotify_Youtube: Danceability, Energy, Duration_ms, Album, Views, Stream и экспорт top20.
Топ-3 ошибки: путать $out и $merge, забыть $unwind перед отзывами, считать skip(5) фильтром по цифре 5.
Выполнимые примеры
Цена жилья в Барселоне
Задача 1 группирует Barcelona listings по диапазонам цены за ночь.
db.listingsAndReviews.aggregate([
{ $match: { "address.market": "Barcelona" } },
{ $bucket: { groupBy: "$price", boundaries: [0, 50, 100, 1000], default: "1000+", output: { listings: { $sum: 1 } } } }
]);
reviews как отдельная коллекция
Один отзыв становится одним документом.
db.listingsAndReviews.aggregate([
{ $match: { reviews: { $ne: [] } } },
{ $unwind: "$reviews" },
{ $replaceRoot: { newRoot: "$reviews" } },
{ $out: "reviews" }
]);
Средние оценки restaurants
Сначала разворачиваем grades, затем считаем avg score.
db.restaurants.aggregate([
{ $unwind: "$grades" },
{ $group: { _id: "$name", avgScore: { $avg: "$grades.score" }, grades: { $sum: 1 } } },
{ $sort: { avgScore: -1 } }
]);
total в sales
Для каждого item перемножаем price и quantity, затем суммируем.
db.sales.aggregate([
{ $set: { total: { $sum: { $map: { input: "$items", as: "item", in: { $multiply: ["$$item.price", "$$item.quantity"] } } } } } },
{ $sort: { total: -1 } }
]);
$lookup customers transactions
accounts является массивом, поэтому localField может сопоставляться с foreignField account_id.
db.customers.aggregate([
{ $lookup: { from: "transactions", localField: "accounts", foreignField: "account_id", as: "transactions" } },
{ $project: { name: 1, accounts: 1, transactions_count: { $size: "$transactions" } } }
]);