17. Multiple Analytical Views with $facet

$facet runs multiple sub-pipelines against the same input documents and returns each branch's output as an array in one result document. It is useful for search pages and dashboards that need a result list, counts, and category summaries together.

Put filters before $facet only when they should apply to every branch. Branch-specific filters belong inside their respective sub-pipelines. Keep results small: facet output has document-size and memory constraints that must be considered.

Code Example
db.orders.aggregate([
  {
    $facet: {
      deliveredSummary: [
        { $match: { status: "delivered" } },
        { $group: { _id: null, count: { $sum: 1 } } }
      ],
      statusCounts: [
        { $group: { _id: "$status", count: { $sum: 1 } } },
        { $sort: { count: -1, _id: 1 } }
      ],
      recentOrders: [
        { $sort: { createdAt: -1, _id: -1 } },
        { $limit: 3 },
        { $project: { customerId: 1, status: 1, createdAt: 1 } }
      ]
    }
  }
]);
Key Takeaways
  • $facet runs multiple sub-pipelines.
  • Each branch returns an array.
  • Shared and branch-specific filters belong in different places.
  • Keep facet outputs bounded.
Knowledge Check

How are $facet branch results represented?