facet¶
On this page
Atlas Search facet and count are in preview. The features and the corresponding documentation may change at any time in the preview stage.
The Atlas Search $searchMeta
stage is not available on
shared clusters. $searchMeta
is available only on
dedicated clusters.
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 Explain.
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 Counting. |
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.
Suppose the following index on the sample_mflix.movies
collection.
{ "mappings": { "dynamic": false, "fields": { "genres": { "type": "stringFacet" }, "released": { "type": "date" } } } }
The following query searches for movies released near July 01, 1999
using the $search
stage. It requests a count of the
number of movies in each genre. The query also includes a:
$project
stage to exclude all fields in the documents except thetitle
andreleased
fields and include the metadata results stored in the$$SEARCH_META
variable as the value of a field namednewField
$limit
stage to limit the output to2
documents.
db.movies.aggregate([ { "$search": { "facet": { "operator": { "near": { "path": "released", "origin": ISODate("1999-07-01T00:00:00.000+00:00"), "pivot": 7776000000 } }, "facets": { "genresFacet": { "type": "string", "path": "genres" } } } } }, { $project: { "newField": "$$SEARCH_META", "title": 1, "released": 1 } }, { "$limit": 2 } ])
The query returns the following results:
{ "_id" : ObjectId("573a1393f29313caabcde1ae"), "title" : "Begone Dull Care", "released" : ISODate("1999-07-01T00:00:00Z"), "newField" : { "count" : { "lowerBound" : NumberLong(23026) }, "facet" : { "genresFacet" : { "buckets" : [ { "_id" : "Drama", "count" : NumberLong(13527) }, { "_id" : "Comedy", "count" : NumberLong(6922) }, { "_id" : "Romance", "count" : NumberLong(3615) }, { "_id" : "Crime", "count" : NumberLong(2649) }, { "_id" : "Thriller", "count" : NumberLong(2603) }, { "_id" : "Action", "count" : NumberLong(2505) }, { "_id" : "Documentary", "count" : NumberLong(2041) }, { "_id" : "Adventure", "count" : NumberLong(2016) }, { "_id" : "Horror", "count" : NumberLong(1662) }, { "_id" : "Biography", "count" : NumberLong(1373) } ] } } } } { "_id" : ObjectId("573a13a9f29313caabd2048a"), "title" : "Fara", "released" : ISODate("1999-07-01T00:00:00Z"), "newField" : { "count" : { "lowerBound" : NumberLong(23026) }, "facet" : { "genresFacet" : { "buckets" : [ { "_id" : "Drama", "count" : NumberLong(13527) }, { "_id" : "Comedy", "count" : NumberLong(6922) }, { "_id" : "Romance", "count" : NumberLong(3615) }, { "_id" : "Crime", "count" : NumberLong(2649) }, { "_id" : "Thriller", "count" : NumberLong(2603) }, { "_id" : "Action", "count" : NumberLong(2505) }, { "_id" : "Documentary", "count" : NumberLong(2041) }, { "_id" : "Adventure", "count" : NumberLong(2016) }, { "_id" : "Horror", "count" : NumberLong(1662) }, { "_id" : "Biography", "count" : NumberLong(1373) } ] } } } }
To learn more about these results, see Facet Results.
Examples¶
This example uses the following index definition on the
sample_mflix.movies
collection. The index definition specifies the
following for the fields to index:
Field Name | Data Type |
---|---|
genres | |
year | |
released |
{ "mappings": { "dynamic": false, "fields": { "directors": { "type": "stringFacet" }, "year": { "type": "number" }, "released": { "type": "date" } } } }
The following query searches for movies released between January 01,
2000 and January 31, 2015. It requests metadata on the directors
and year
field.
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": { "directorsFacet": { "type": "string", "path": "directors", "numBuckets" : 7 }, "yearFacet" : { "type" : "number", "path" : "year", "boundaries" : [2000,2005,2010, 2015] } } } } } ])
Atlas Search returns the following results:
{ "count" : { "lowerBound" : NumberLong(13064) }, "facet" : { "yearFacet" : { "buckets" : [ { "_id" : 2000, "count" : NumberLong(3283) }, { "_id" : 2005, "count" : NumberLong(4365) }, { "_id" : 2010, "count" : NumberLong(5123) } ] }, "directorsFacet" : { "buckets" : [ { "_id" : "Takashi Miike", "count" : NumberLong(29) }, { "_id" : "Johnnie To", "count" : NumberLong(23) }, { "_id" : "Steven Soderbergh", "count" : NumberLong(21) }, { "_id" : "Michael Winterbottom", "count" : NumberLong(19) }, { "_id" : "Ken Loach", "count" : NumberLong(16) }, { "_id" : "Ki-duk Kim", "count" : NumberLong(16) }, { "_id" : "Ridley Scott", "count" : NumberLong(15) } ] } } }
The results show a count of the following in the
sample_mflix.movies
collection:
- Number of movies from the year 2000, inclusive lower bound, to 2015, exclusive upper bound, that Atlas Search returned for the query
- Number of movies for each director that Atlas Search returned for the query