Lookup, Unwind, Faceted Search, and Bucketing

Advanced Aggregation

Beyond basic grouping and filtering, MongoDB's aggregation framework supports joining collections, flattening arrays, faceted search, and bucketing — enabling complex, SQL-defying analytical queries in a single pipeline.

1. $lookup — Joining Collections

$lookup performs a left outer join, pulling in related documents from another collection.

db.orders.aggregate([
  { $lookup: {
      from: "customers",
      localField: "customerId",
      foreignField: "_id",
      as: "customerInfo"
  }},
  { $unwind: "$customerInfo" }
])

2. $unwind — Flattening Arrays

$unwind deconstructs an array field, producing one output document per array element.

db.orders.aggregate([
  { $unwind: "$items" },
  { $group: { _id: "$items.productId", totalQty: { $sum: "$items.quantity" } } }
])

3. $facet — Faceted Search

$facet runs multiple aggregation pipelines in parallel on the same input — perfect for e-commerce filter sidebars showing counts across categories, price ranges, and brands simultaneously.

db.products.aggregate([
  { $facet: {
      byCategory: [ { $group: { _id: "$category", count: { $sum: 1 } } } ],
      byPriceRange: [
        { $bucket: {
            groupBy: "$price",
            boundaries: [0, 1000, 5000, 20000, 100000],
            default: "Other",
            output: { count: { $sum: 1 } }
        }}
      ],
      totalCount: [ { $count: "total" } ]
  }}
])

4. $bucket and $bucketAuto — Grouping into Ranges

// Manual boundaries
db.products.aggregate([
  { $bucket: {
      groupBy: "$price",
      boundaries: [0, 500, 2000, 10000],
      default: "10000+",
      output: { count: { $sum: 1 }, products: { $push: "$name" } }
  }}
])

// Automatic even distribution into 4 buckets
db.products.aggregate([
  { $bucketAuto: { groupBy: "$price", buckets: 4 } }
])
Common Issue: $lookup can be slow on large collections without an index on the foreign field. Always index foreignField before joining at scale.

5. $graphLookup — Recursive Relationships

For hierarchical data (org charts, category trees), $graphLookup performs recursive lookups in a single stage.

db.employees.aggregate([
  { $graphLookup: {
      from: "employees",
      startWith: "$managerId",
      connectFromField: "managerId",
      connectToField: "_id",
      as: "managementChain"
  }}
])

6. Advanced Aggregation Checklist

  • ✅ Join collections using $lookup
  • ✅ Flatten arrays using $unwind
  • ✅ Build faceted search results with $facet
  • ✅ Group values into ranges with $bucket / $bucketAuto
  • ✅ Traverse recursive relationships with $graphLookup
Key Takeaway: Advanced aggregation stages let MongoDB handle analytics workloads that once required a separate data warehouse — joins, faceting, and hierarchies, all inside the database.

Ready to master MongoDB?

Build real-world MongoDB-powered applications with hands-on projects, mentor-led sessions, and placement support.

Explore Course