Start learning free

LESSON 56 OF 66 · NOSQL: MONGODB

Embed or Reference? in Python

Practice

An order needs two kinds of related data: the items it bought and the customer who placed it. The shop stores them in two ways. The items are embedded: a list inside the order document. The customer is referenced: the order only stores customer_id, the _id of a document in the customers collection.

Embed what belongs to the parent and is read with it: an item never exists without its order, and showing an order always shows its items. Reference what stands on its own and is shared: one customer places many orders, and when an email changes, you fix one customer document instead of a copy in every order.

To read orders together with their customers, $lookup joins them in, like SQL's JOIN. It takes four settings: from, the other collection; localField and foreignField, the two fields that must be equal, like ON; and as, the new field. That field always holds a list, since several documents could match. Run the other way round with db.customers.aggregate(pipeline), this gives each customer a list of their orders:

pipeline = [
    {"$lookup": {
        "from": "orders",
        "localField": "_id",
        "foreignField": "customer_id",
        "as": "orders",
    }},
]

Each order has exactly one customer, so an $unwind on the new field turns its one-item list into the customer's document. The starting code prints order 1 and sorts the orders by _id. Your finished script prints:

{'customer_id': 1, 'ordered': '2026-03-02', 'status': 'paid', 'items': [{'product': 'Mug', 'quantity': 2, 'unit_price': 12}, {'product': 'Pen', 'quantity': 5, 'unit_price': 2}]}
1 paid Ana Pop
2 paid Ben Ortiz
3 paid Ana Pop
4 shipped Chloe Ng
5 paid Dan Weber
6 cancelled Ben Ortiz
7 paid Chloe Ng

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 $sort, add a $lookup stage that brings in customers, matches the order's customer_id to the customer's _id and puts the matches in customer; then an $unwind on "$customer". Loop over db.orders.aggregate(pipeline) and print each order's _id, status and customer name.


Assignment
Follow the Coding Tutorial to join each order's customer in with $lookup, unwind it and print every order with its customer's name.


Hint
localField is a field of the documents the pipeline runs on, the orders; foreignField is a field of the from collection, the customers. After the $unwind, order["customer"] is a whole customer document.


STEP 1 OF 7
    Ctrl + Enter to check

    Mongo Embed Or Reference in Python

    Keep going with Python1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free