Filter search results
In this guide you will see how to configure and use Meilisearch filters in a hypothetical movie database.
Configure index settings
Suppose you have a collection of movies called movie_ratings
containing the following fields:
[
{
"id": 458723,
"title": "Us",
"director": "Jordan Peele",
"release_date": 1552521600,
"genres": [
"Thriller",
"Horror",
"Mystery"
],
"rating": {
"critics": 86,
"users": 73
},
},
…
]
If you want to filter results based on an attribute, you must first add it to the filterableAttributes
list:
curl \
-X PUT 'http://localhost:7700/indexes/movie_ratings/settings/filterable-attributes' \
-H 'Content-Type: application/json' \
--data-binary '[
"genres",
"director",
"release_date",
"ratings"
]'
This step is mandatory and cannot be done at search time. Updating filterableAttributes
requires Meilisearch to re-index all your data, which will take an amount of time proportionate to your dataset size and complexity.
NOTE
By default, filterableAttributes
is empty. Filters do not work without first explicitly adding attributes to the filterableAttributes
list.
Use filter
when searching
After updating the filterableAttributes
index setting, you can use filter
to fine-tune your search results.
filter
is a search parameter you may use at search time. filter
accepts filter expressions built using any attributes present in the filterableAttributes
list.
The following code sample returns Avengers
movies released after 18 March 1995:
curl \
-X POST 'http://localhost:7700/indexes/movie_ratings/search' \
-H 'Content-Type: application/json' \
--data-binary '{
"q": "Avengers",
"filter": "release_date > 795484800"
}'
Use dot notation to filter results based on a document's nested fields. The following query only returns thrillers with good user reviews:
curl \
-X POST 'http://localhost:7700/indexes/movie_ratings/search' \
-H 'Content-Type: application/json' \
--data-binary '{
"q": "thriller",
"filter": "rating.users >= 90"
}'
You can also combine multiple conditions. For example, you can limit your search so it only includes Batman
movies directed by either Tim Burton
or Christopher Nolan
:
curl \
-X POST 'http://localhost:7700/indexes/movie_ratings/search' \
-H 'Content-Type: application/json' \
--data-binary '{
"q": "Batman",
"filter": "release_date > 795484800 AND (director = \"Tim Burton\" OR director = \"Christopher Nolan\")"
}'
Here, the parentheses are mandatory: without them, the filter would return movies directed by Tim Burton
and released after 1995 or any film directed by Christopher Nolan
, without constraints on its release date. This happens because AND
takes precedence over OR
.
If you only want recent Planet of the Apes
movies that weren't directed by Tim Burton
, you can use this filter:
curl \
-X POST 'http://localhost:7700/indexes/movie_ratings/search' \
-H 'Content-Type: application/json' \
--data-binary '{
"q": "Planet of the Apes",
"filter": "release_date > 1577884550 AND (NOT director = \"Tim Burton\")"
}' \
NOT director = "Tim Burton"
will include both documents that do not contain "Tim Burton"
in its director
field and documents without a director
field. To return only documents that have a director
field, expand the filter expression with the EXISTS
operator:
release_date > 1577884550 AND (NOT director = "Tim Burton" AND director EXISTS)
WARNING
Synonyms don't apply to filters. Meaning, if you have SF
and San Francisco
set as synonyms, filtering by SF
and San Francisco
will show you different results.