Faceted Results and Bucketing

$facet runs several independent sub-pipelines over the same input stream and returns one document whose fields are their result arrays. It powers a search page showing results, a count per category and a price histogram in one round trip and one pass.

Two independent summaries from one pass
db.orders.aggregate([
  { $unwind: '$items' },
  { $facet: {
      byStatus: [{ $sortByCount: '$status' }, { $limit: 2 }],
      spend: [{ $group: { _id: null, units: { $sum: '$items.qty' },
                          max: { $max: '$items.price' } } }] } }
])
Output
[
  {
    byStatus: [ { _id: 'delivered', count: 20 }, { _id: 'shipped', count: 3 } ],
    spend: [ { _id: null, units: 37, max: 640 } ]
  }
]

Both branches see the 20 unwound line items, not the 14 orders. $sortByCount is the shorthand every faceted search needs: $group by an expression with { $sum: 1 }, sorted descending, counter named count. Put shared filtering before the $facet, since branches cannot see each other, and cap every branch with $limit: each buffers into one output document, so the whole facet result must fit in 16 MiB.

$bucket sorts documents into ranges you choose. boundaries must ascend and share one type; each bucket covers [lower, upper) and takes the lower bound as its _id. A value outside every range throws an error unless you supply default.

Grouping order totals into fixed ranges
db.orders.aggregate([
  { $set: { total: { $sum: { $map: { input: '$items', as: 'i',
                             in: { $multiply: ['$$i.qty', '$$i.price'] } } } } } },
  { $bucket: { groupBy: '$total', boundaries: [0, 200, 400, 800],
               default: 'other', output: { n: { $sum: 1 }, avg: { $avg: '$total' } } } }
])
Output
[
  { _id: 0, n: 5, avg: 147 },
  { _id: 200, n: 5, avg: 307 },
  { _id: 400, n: 4, avg: 593.75 }
]

When you do not know the distribution, $bucketAuto picks boundaries: three buckets over the same totals return counts of 5, 5 and 4 for _id ranges { min: 135, max: 255 }, { min: 255, max: 440 } and { min: 440, max: 655 }. It balances the counts, so widths differ, and a granularity option ("R5", "E6", "POWERSOF2") rounds boundaries to a preferred-number series.