Data Transformations & Lookup
Data Transformations & Lookup
Beyond simple grouping and filtering, the Aggregation Framework allows for complex relational-like joins and multi-dimensional analytics.
🏗️ 1. $lookup (The Join)
The $lookup stage performs a left outer join to a collection in the same database.
Basic Lookup
db.orders.aggregate([
{
$lookup: {
from: "products", // Collection to join
localField: "productId", // Field from the 'orders' collection
foreignField: "_id", // Field from the 'products' collection
as: "productDetails" // Output array field
}
}
]);🚀 2. $unwind (Array Deconstruction)
$unwind deconstructs an array field from the input documents to output a document for each element. This is often used immediately after a $lookup to flatten the joined data.
Mongo Shell
db.orders.aggregate([
{ $lookup: { from: "products", localField: "productId", foreignField: "_id", as: "product" } },
{ $unwind: "$product" } // Converts 'product' array into a single object
]);PyMongo
pipeline = [
{"$lookup": {"from": "products", "localField": "pid", "foreignField": "_id", "as": "p"}},
{"$unwind": "$p"}
]⚡ 3. $facet (Multi-faceted Analytics)
$facet allows you to process multiple aggregation pipelines within a single stage on the same set of input documents. It is perfect for creating dashboards where you need multiple metrics (e.g., total count, average price, and distribution) in one go.
db.products.aggregate([
{
$facet: {
"priceStats": [
{ $match: { price: { $exists: true } } },
{ $group: { _id: null, avgPrice: { $avg: "$price" } } }
],
"categoryCount": [
{ $group: { _id: "$category", count: { $sum: 1 } } },
{ $sort: { count: -1 } }
]
}
}
]);🖼️ 4. MongoDB Views
A View is a read-only queryable object whose contents are defined by an aggregation pipeline. They behave like collections but do not store data themselves.
Creating a View
db.createView(
"orderSummary", // View name
"orders", // Source collection
[ // Pipeline
{ $match: { status: "shipped" } },
{ $project: { _id: 1, customerId: 1, total: 1 } }
]
);💡 Best Practices
- Join Sparingly: Frequent use of
$lookupmight indicate that your data model is too relational. Consider embedding data if it is frequently accessed together. - Filter Before Joining: Always use a
$matchstage before a$lookupto reduce the number of joins performed. - Unwind with Caution:
$unwindcan significantly increase the number of documents in your pipeline. Use it only when necessary.