An order in the shop holds a list of items: order 1 bought 2 Mugs at 12 and 5 Pens at 2. To total the revenue per product, you want to group the items by product. But $group puts each whole document in one group, and one order can hold several products.
$unwind splits the list. {"$unwind": "$items"} copies each order once per item, and in each copy items holds one item instead of the list. Order 1 becomes two documents, one with the Mug and one with the Pen, like two rows of an order_items table in SQL. It works on any list field. This pipeline, run with db.products.aggregate(pipeline), counts the products that carry each tag:
pipeline = [
{"$unwind": "$tags"},
{"$group": {"_id": "$tags", "products": {"$sum": 1}}},
]
After $unwind, a dot path like "$items.product" reads one field of the single item. {"$multiply": [a, b]} is a times b for each document, and $sum adds those up in each group, like SQL's SUM(quantity * unit_price). Stages run in order, each feeding the next, so the $match at the top drops cancelled orders before anything is unwound.
Your finished script prints each product's revenue, highest first:
Mug 84 Lamp 58 Teapot 44 Notebook 35 Pen 30 Plant 15
The lesson runs on an in-memory MongoDB that already holds the shop; the same code runs unchanged on a real MongoDB server.
Your task: below the $match, add an $unwind stage on "$items", a $group stage by "$items.product" whose revenue sums quantity times unit price, and a $sort on revenue, highest first. Then run the pipeline on db.orders and print each row's _id and revenue.
Assignment
Follow the Coding Tutorial to unwind the orders' items, group them by product with their revenue, sort the groups and print them.
Hint
After $unwind, items is one item, not a list, so "$items.quantity" and "$items.unit_price" are single numbers you can multiply. In $sort, -1 puts the biggest first.
Free plan: 30 tutor messages. PRO is unlimited.
