How to use Facets with Atlas Search¶
The Atlas Search $searchMeta
stage is not available on
shared clusters. $searchMeta
is available only on
dedicated clusters.
This tutorial describes how to create an index with a facet
definition on string, date, and numeric fields
in the sample_mflix.movies
collection. It shows how to run an Atlas Search
query against those fields for results grouped by values for the string
field and by ranges for the date and numeric fields, including the
count for each of those groups. It takes you through the following
steps:
- Set up an Atlas Search index with facet definition on the
genres
,released
, andyear
fields in thesample_mflix.movies
collection. - Run Atlas Search query against the
released
field in thesample_mflix.movies
collection for results grouped by values for thegenres
field and by ranges for theyear
field.
Prerequisites¶
To complete these tutorials, you must have the following:
An Atlas cluster running one of the following versions:
- MongoDB 4.4.11 or later
- MongoDB 5.0.4 or later
- The sample datasets loaded into your Atlas cluster. You will use a collection with movie data from the Atlas sample dataset.
mongosh
on your local machine.
Create the Atlas Search Index for Facet¶
In this section, you will create an Atlas Search index on the genres
,
year
, and released
fields in the sample_mflix.movies
collection.
Navigate to the Atlas Search page for your project.¶
- If it is not already displayed, select the organization that contains your desired project from the Organizations menu in the navigation bar.
- If it is not already displayed, select your desired project from the Projects menu in the navigation bar.
- Click your cluster's name.
- Click the Search tab.
Click Create Index.¶
Select the JSON Editor Configuration Method and click Next.¶
The Visual Editor Configuration Method doesn't support stringFacet.
Enter the Index Name, and set the Database and Collection.¶
In the Index Name field, enter
default
.The index name defaults to default. You can leave the default name in place or choose one of your own.
NoteIf you name your index
default
, you don't need to specify anindex
parameter when using the $search pipeline stage. Otherwise, you must specify the index name using theindex
parameter.Index names must be unique within their namespace.
- In the Database and Collection section, find the
sample_mflix
database, and select themovies
collection.
Replace the default index definition with the following index definition and then click Next.¶
{ "mappings": { "dynamic": false, "fields": { "genres": { "type": "stringFacet" }, "year": { "type": "number" }, "released": { "type": "date" } } } }
The index definition above uses lucene.standard
as the default
analyzer for both indexing and querying the fields and specifies the
following for the fields to index:
Field Name | Data Type |
---|---|
genres | |
year | |
released |
Click Create Search Index.¶
Close the You're All Set! Modal Window.¶
A modal window appears to let you know your index is building. Click the Close button.
Wait for the index to finish building.¶
The index should take about one minute to build. While it is
building, the Status column reads Build in
Progress
. When it is finished building, the
Status column reads Active
.
Search the Collection¶
You can use facet in queries that use the
$search
and $searchMeta
stages. In this
section, connect to your Atlas cluster and the run the sample query
against the sample_mflix.movies
collection using the
$searchMeta
stage. MongoDB recommends using the
$searchMeta
stage to retrieve metadata results only.
Connect to your cluster in mongosh
.¶
Open mongosh
in a terminal window and
connect to your cluster. For detailed instructions on connecting,
see Connect via mongosh
.
Run the following query on the movies
collection.¶
The following query searches for movies released near November 11, 1921. It specifies a pivot
distance from
origin
of approximately three months. It requests metadata on the
genres
and year
field. The query requests a count of the:
- Number of movies in each genre in the
genres
string array field - Number of movies in the years 1910 to 1939, inclusive
db.movies.aggregate([ { "$searchMeta": { "facet": { "operator": { "near": { "path": "released", "origin": ISODate("1921-11-01T00:00:00.000+00:00"), "pivot": 7776000000 } }, "facets": { "genresFacet": { "type": "string", "path": "genres" }, "yearFacet" : { "type" : "number", "path" : "year", "boundaries" : [1910,1920,1930,1940] } } } } } ])
The query returns the following results:
1 { 2 "count" : { 3 "lowerBound" : NumberLong(23026) 4 }, 5 "facet" : { 6 "genresFacet" : { 7 "buckets" : [ 8 { "_id" : "Drama", "count" : NumberLong(13527) }, 9 { "_id" : "Comedy", "count" : NumberLong(6922) }, 10 { "_id" : "Romance", "count" : NumberLong(3615) }, 11 { "_id" : "Crime", "count" : NumberLong(2649) }, 12 { "_id" : "Thriller", "count" : NumberLong(2603) }, 13 { "_id" : "Action", "count" : NumberLong(2505) }, 14 { "_id" : "Documentary", "count" : NumberLong(2041) }, 15 { "_id" : "Adventure", "count" : NumberLong(2016) }, 16 { "_id" : "Horror", "count" : NumberLong(1662) }, 17 { "_id" : "Biography", "count" : NumberLong(1373) } 18 ] 19 }, 20 "yearFacet" : { 21 "buckets" : [ 22 { "_id" : 1910, "count" : NumberLong(23) }, 23 { "_id" : 1920, "count" : NumberLong(89) }, 24 { "_id" : 1930, "count" : NumberLong(308) } 25 ] 26 } 27 } 28 }
The results show metadata results for two types of facet search. The
genresFacet
document shows the number of movies in each genre and
the yearFacet
document shows a count of the number of movies
within the boundaries:
1910
, inclusive lower bound the1910
bucket1920
, exclusive upper bound for the1910
bucket and inclusive lower bound for the1920
bucket1930
, exclusive upper bound for the1920
bucket and inclusive lower bound for the1930
bucket