facet
On this page
Atlas Search facet and count are in preview, but can be used in production applications. If there are any syntax or behavior changes between the preview stage and general availability (GA), we will proactively communicate before introducing any breaking changes. The MongoDB Cloud Support team will help troubleshoot any issues related to using this feature as part of your contract.
facet
is only available on Atlas clusters running one of the
following versions:
- MongoDB 4.4.11 or later
- MongoDB 5.0.4 or later
You can't run facet
queries with Retrieve Query Plan and Execution Statistics.
Definition
facet
The
facet
collector groups results by values or ranges in the specified faceted fields and returns the count for each of those groups.You can use
facet
with both the$search
and$searchMeta
stages. MongoDB recommends usingfacet
with the$searchMeta
stage to retrieve metadata results only for the query. To retrieve metadata results and query results using the$search
stage, you must use the$$SEARCH_META
aggregation variable. SeeSEARCH_META
Aggregation Variable to learn more.
Syntax
facet
has the following syntax:
{ "$searchMeta"|"$search": { "index": <index name>, // optional, defaults to "default" "facet": { "operator": { <operator-specifications> }, "facets": { <facet-definitions> } } } }
Fields
Field | Type | Required? | Description |
---|---|---|---|
facets | document | yes | Information for bucketing the data
for each facet. You must specify at least one
Facet Definition. |
operator | document | yes | Operator to use to perform the facet over. |
Facet Definition
The facet definition document contains the facet name and options specific to a type of facet. Atlas Search supports the following types of facets:
String Facets
String facets allow you to narrow down Atlas Search results based on the most frequent string values in the specified string field. Note that the string field must be indexed as stringFacet.
Syntax
String facets have the following syntax:
{ "$searchMeta": { "facet":{ "operator": { <operator-specification> }, "facets": { "<facet-name>" : { "type" : "string", "path" : "<field-path>", "numBuckets" : <number-of-categories>, } } } } }
Options
Option | Type | Description | Required? |
---|---|---|---|
numBuckets | int | Maximum number of facet categories to return in the results.
Value must be less than or equal to 1000 . If specified,
Atlas Search may return fewer categories than requested if the data is
grouped into fewer categories than your requested number. If
omitted, defaults to 10 , which means that Atlas Search will return
only the top 10 facet categories by count. | no |
path | string | Field path to facet on. You can specify a field that is
indexed as a stringFacet. | yes |
type | string | Type of facet. Value must be string . | yes |
Example
The following example uses an index named default
on the
sample_mflix.movies
collection. The genres
field in the
collection is indexed as type stringFacet
and the year
field is indexed as number.
{ "mappings": { "dynamic": false, "fields": { "genres": { "type": "stringFacet" }, "year": { "type": "number" } } } }
The query uses the $searchMeta
stage to search the
year
field in the movies
collection for movies from 2000 to
2015 and retrieve a count of the number of movies in each genre.
db.movies.aggregate([ { "$searchMeta": { "facet": { "operator": { "range": { "path": "year", "gte": 2000, "lte": 2015 } }, "facets": { "genresFacet": { "type": "string", "path": "genres" } } } } } ])
This query returns the following results:
[ { count: { lowerBound: Long("13718") }, facet: { genresFacet: { buckets: [ { _id: 'Drama', count: Long("7759") }, { _id: 'Comedy', count: Long("3937") }, { _id: 'Romance', count: Long("1916") }, { _id: 'Thriller', count: Long("1705") }, { _id: 'Documentary', count: Long("1703") }, { _id: 'Action', count: Long("1558") }, { _id: 'Crime', count: Long("1475") }, { _id: 'Adventure', count: Long("1111") }, { _id: 'Horror', count: Long("1008") }, { _id: 'Biography', count: Long("877") } ] } } } ]
To learn more about these results, see Facet Results.
Numeric Facets
Numeric facets allow you to determine the frequency of numeric values in your search results by breaking the results into separate ranges of numbers.
Syntax
Numeric facets have the following syntax:
{ "$searchMeta": { "facet":{ "operator": { <operator-specification> }, "facets": { "<facet-name>" : { "type" : "number", "path" : "<field-path>", "boundaries" : <array-of-numbers>, "default": "<bucket-name>" } } } } }
Options
Option | Type | Description | Required? |
---|---|---|---|
boundaries | array of numbers | List of numeric values, in ascending order, that specify the boundaries for each bucket. You must specify at least two boundaries. Each adjacent pair of values acts as the inclusive lower bound and the exclusive upper bound for the bucket. You can specify any combination of values of the following BSON types:
| yes |
default | string | Name of an additional bucket that counts documents returned from
the operator that do not fall within the specified boundaries.
If omitted, Atlas Search includes the results of the facet operator
that do not fall under a specified bucket also, but doesn't
include it in any bucket counts. | no |
path | string | Field path to facet on. You can specify a field that is
indexed as a number. | yes |
type | string | Type of facet. Value must be number . | yes |
Example
The following example uses an index named default
on the
sample_mflix.movies
collection. The year
field in the
collection is indexed as type number.
{ "mappings": { "dynamic": false, "fields": { "year": [ { "type": "number" } ] } } }
The query uses the $searchMeta
stage to search the
year
field in the movies
collection for movies between
the years 1980
to 2000
and retrieve metadata results for the
query. The query specifies three buckets:
1980
, inclusive lower bound for this bucket1990
, exclusive upper bound for the1980
bucket and inclusive lower bound for this bucket2000
, exclusive upper bound for the1990
bucket
The query also specifies a default
bucket named other
to
retrieve results of the query that don't fall under any of the
specified boundaries.
db.movies.aggregate([ { "$searchMeta": { "facet": { "operator": { "range": { "path": "year", "gte": 1980, "lte": 2000 } }, "facets": { "yearFacet": { "type": "number", "path": "year", "boundaries": [1980,1990,2000], "default": "other" } } } } } ])
This query returns the following results:
{ "count" : { "lowerBound" : NumberLong(6472) }, "facet" : { "yearFacet" : { "buckets" : [ { "_id" : 1980, "count" : NumberLong(2081) }, { "_id" : 1990, "count" : NumberLong(3773) }, { "_id" : "other", "count" : NumberLong(618) } ] } } }
To learn more about these results, see Facet Results.
Date Facets
Date facets allow you to narrow down search results based on a date.
Syntax
Date facets have the following syntax:
{ "$searchMeta": { "facet":{ "operator": { <operator-specification> }, "facets": { "<facet-name>" : { "type" : "date", "path" : "<field-path>", "boundaries" : <array-of-dates>, "default": "<bucket-name>" } } } } }
Options
Option | Type | Description | Required? |
---|---|---|---|
boundaries | array of numbers | List of date values that specify the boundaries for each bucket. You must specify:
Each adjacent pair of values acts as the inclusive lower bound and the exclusive upper bound for the bucket. | yes |
default | string | Name of an additional bucket that counts documents returned from
the operator that do not fall within the specified boundaries.
If omitted, Atlas Search includes the results of the facet operator
that do not fall under a specified bucket also, but Atlas Search
doesn't include these results in any bucket counts. | no |
path | string | Field path to facet on. You can specify a field that is
indexed as a date. | yes |
type | string | Type of facet. Value must be date . | yes |
Example
The following example uses an index named default
on the
sample_mflix.movies
collection. The released
field in the
collection is indexed as type date.
{ "mappings": { "dynamic": false, "fields": { "released": [ { "type": "date" } ] } } }
The query uses the $searchMeta
stage to search the
released
field in the movies
collection for movies between
the years 2000
to 2015
and retrieve metadata results for the
query string. The query specifies four buckets:
2000-01-01
, inclusive lower bound for this bucket2005-01-01
, exclusive upper bound for the2000-01-01
bucket and inclusive lower bound for this bucket2010-01-01
, exclusive upper bound for the2005-01-01
bucket and inclusive lower bound for this bucket2015-01-01
, exclusive upper bound for the2010-01-01
bucket
The query also specifies a default
bucket named other
to
retrieve results of the query that don't fall under any of the
specified boundaries.
db.movies.aggregate([ { "$searchMeta": { "facet": { "operator": { "range": { "path": "released", "gte": ISODate("2000-01-01T00:00:00.000Z"), "lte": ISODate("2015-01-31T00:00:00.000Z") } }, "facets": { "yearFacet": { "type": "date", "path": "released", "boundaries": [ISODate("2000-01-01"), ISODate("2005-01-01"), ISODate("2010-01-01"), ISODate("2015-01-01")], "default": "other" } } } } } ])
This query returns the following results:
{ "count" : { "lowerBound" : NumberLong(13064) }, "facet" : { "releaseFacet" : { "buckets" : [ { "_id" : ISODate("2000-01-01T00:00:00Z"), "count" : NumberLong(3242) }, { "_id" : ISODate("2005-01-01T00:00:00Z"), "count" : NumberLong(4266) }, { "_id" : ISODate("2010-01-01T00:00:00Z"), "count" : NumberLong(5445) }, { "_id" : "other", "count" : NumberLong(111) } ] } } }
To learn more about these results, see Facet Results.
Facet Results
For a facet query, Atlas Search returns a mapping of the defined facet names
to an array of buckets for that facet in the results. The facet result
document contains the buckets
option, which is an array of
resulting buckets for the facet. Each facet bucket document in the
array has the following fields:
Option | Type | Description |
---|---|---|
_id | object | Unique identifier that identifies this facet bucket. This value
matches the type of data that is being faceted on. |
count | int | Count of documents in this facet bucket. To learn more about the
count field, see Count Search Results. |
SEARCH_META
Aggregation Variable
When you run your query using the $search
stage, Atlas Search
stores the metadata results in the $$SEARCH_META
variable and
returns only the search results. You can use the $$SEARCH_META
variable in all the supported aggregation pipeline stages to view the metadata
results for your $search
query.
You can't use the $$SEARCH_META
variable to retrieve metadata
results for queries over sharded collections.
MongoDB recommends using the $$SEARCH_META
variable only if you
need both the search results and the metadata results. Otherwise, use
the:
$search
stage for just the search results.$searchMeta
stage for just the metadata results.
Examples
The following examples use the sample_mflix.movies
collection.
To learn more about these results, see Facet Results.