For AI agents: a documentation index is available at https://www.mongodb.com/docs/llms.txt — markdown versions of all pages are available by appending .md to any URL path.
Docs Menu

$facet (aggregation stage)

$facet

Processes multiple aggregation pipelines within a single stage on the same set of input documents. Each sub-pipeline has its own field in the output document where its results are stored as an array of documents.

The $facet stage allows you to create multi-faceted aggregations which characterize data across multiple dimensions, or facets, within a single aggregation stage. Multi-faceted aggregations provide multiple filters and categorizations to guide data browsing and analysis. Retailers commonly use faceting to narrow search results by creating filters on product price, manufacturer, size, etc.

Input documents are passed to the $facet stage only once, enabling various aggregations on the same set of input documents.

You can use $facet for deployments hosted in the following environments:

  • MongoDB Atlas: The fully managed service for MongoDB deployments in the cloud

The $facet stage has the following form:

{ $facet:
{
<outputField1>: [ <stage1>, <stage2>, ... ],
<outputField2>: [ <stage1>, <stage2>, ... ],
...
}
}

Specify the output field name for each specified pipeline.

As each stage in a $facet executes, the resulting document is limited to 100 megabytes. Note the allowDiskUse flag doesn't affect the 100 megabyte size limit, since $facet can't spill to disk.

If a $facet stage constructs a document where the size exceeds the 100 megabyte limit, MongoDB returns an ExceededMemoryLimit error.

The final output document is subject to the 16 mebibyte BSON document size limit. If it exceeds 16 mebibytes, the aggregation produces an error.

Facet-related aggregation stages categorize and group incoming documents. Specify any of the following facet-related stages within different $facet sub-pipeline's <stage> to perform a multi-faceted aggregation:

Other aggregation stages can also be used with $facet with the following exceptions:

Each sub-pipeline within $facet is passed the exact same set of input documents. These sub-pipelines are completely independent of one another and the document array output by each is stored in separate fields in the output document. The output of one sub-pipeline can not be used as the input for a different sub-pipeline within the same $facet stage. If further aggregations are required, add additional stages after $facet and specify the field name, <outputField>, of the desired sub-pipeline output.

Pipeline order determines how the $facet stage uses indexes.

  • If the $facet stage is the first stage in a pipeline, the stage will perform a COLLSCAN. The $facet stage does not make use of indexes if it is the first stage in the pipeline.

  • If the $facet stage comes later in the pipeline and earlier stages have used indexes, $facet will not trigger a COLLSCAN during execution.

For example, $match or $sort stages that come before a $facet stage can make use of indexes and the $facet will not trigger a COLLSCAN.

For optimization suggestions, see: Aggregation Pipeline Optimization.

The examples on this page use data from the sample_mflix dataset. For details on how to load this dataset into your self-managed MongoDB deployment, see Load the Sample Dataset. If you made any modifications to the sample databases, you may need to drop and recreate the databases to run the examples on this page.

The following aggregation pipeline uses the movies collection to categorize films across multiple dimensions. A $match stage limits the input to movies with a runtime greater than 1,000 minutes. The $facet stage runs three sub-pipelines in parallel using $sortByCount, $bucket, and $bucketAuto. MongoDB fetches input documents from the movies collection only once, at the beginning of the operation:

db.movies.aggregate( [
{ $match: { runtime: { $gt: 1000 } } },
{
$facet: {
"categorizedByGenres": [
{ $unwind: "$genres" },
{ $sortByCount: "$genres" }
],
"categorizedByRuntime": [
{
$bucket: {
groupBy: "$runtime",
boundaries: [ 1000, 1200, 1400 ],
default: "Other",
output: {
"count": { $sum: 1 },
"titles": { $push: "$title" }
}
}
}
],
"categorizedByYear(Auto)": [
{
$bucketAuto: {
groupBy: "$year",
buckets: 4
}
}
]
}
}
] )
[
{
categorizedByGenres: [
{ _id: 'Sport', count: 1 },
{ _id: 'Documentary', count: 1 },
{ _id: 'Action', count: 1 },
{ _id: 'Drama', count: 1 },
{ _id: 'Adventure', count: 1 },
{ _id: 'History', count: 1 }
],
categorizedByRuntime: [
{ _id: 1000, count: 1, titles: [ 'Baseball' ] },
{ _id: 1200, count: 1, titles: [ 'Centennial' ] }
],
'categorizedByYear(Auto)': [
{ _id: { min: 1978, max: 1994 }, count: 1 },
{ _id: { min: 1994, max: 1994 }, count: 1 }
]
}
]

To learn more about related pipeline stages, see the $bucketAuto, $sortByCount, and $limit guides.