← К оглавлению занятия
⚡ Кратко: суть занятия
Первая часть практической отработки MongoDB строится вокруг aggregation pipeline.
$bucket распределяет документы по диапазонам: например цены жилья в Барселоне.
$unwind превращает каждый элемент массива reviews в отдельный документ.
$set и $unset помогают превратить вложенный объект отзыва в плоский документ.
$out записывает результат агрегации в новую коллекцию reviews.
$merge обновляет существующую коллекцию, когда нужно добавить вычисленные поля.
$map, $multiply и $sum позволяют посчитать total по массиву items в sales.
Топ-3 ошибки: забыть $match перед $bucket, использовать $out вместо $merge для обновления, неправильно обратиться к $$item внутри $map.
Разбор решений
Задача 1
db.listingsAndReviews.aggregate([
{ $match: { "address.country_code": "ES", "address.market": "Barcelona" } },
{ $bucket: { groupBy: "$price", boundaries: [0, 50, 100, 1000], default: "EXPENSIVE", output: { count: { $sum: 1 }, property: { $push: "$name" } } } }
])
Сначала выбираем Барселону, затем раскладываем цены по диапазонам.
Задача 2
db.listingsAndReviews.aggregate([
{ $match: { reviews: { $ne: [] } } },
{ $project: { _id: 0, reviews: 1 } },
{ $unwind: "$reviews" },
{ $set: { date: "$reviews.date", listing_id: "$reviews.listing_id", reviewer_id: "$reviews.reviewer_id", reviewer_name: "$reviews.reviewer_name", comments: "$reviews.comments" } },
{ $unset: "reviews" },
{ $out: "reviews" }
])
$out финализирует новую коллекцию.
Задача 4
db.restaurants.aggregate([
{ $set: { avg_score: { $avg: "$grades.score" }, number_of_reviews: { $size: "$grades" } } },
{ $merge: { into: "restaurants", whenMatched: "merge" } }
])
$merge выбран потому, что обновляются существующие документы.
Задача 5
db.sales.aggregate([
{ $addFields: { total: { $sum: { $map: { input: "$items", as: "item", in: { $multiply: ["$$item.price", "$$item.quantity"] } } } } } },
{ $merge: { into: "sales", whenMatched: "merge" } }
])
$$item обращается к текущему элементу массива внутри $map.
Проверить по документации: если имена полей в вашей учебной коллекции отличаются от примеров, адаптируйте запрос после просмотра реального документа.