Faceting
On this page
Facets let you create categories on a select group of attributes, so users can refine their search. For example, on an index of books, helpful facets might be author and genre. Algolia also calculates results for each facet. It allows you to display facets and facet counts so that users can filter results (for example, by author or genre).
Faceting is a common search feature that Algolia provides out of the box. To leverage faceting, you need to enable it on a per-attribute basis with the attributesForFaceting
parameter. It allows you to:
- List all possible values for the selected attributes and return contextual values and counts with each search result.
- Compute a facet count or the number of records matching each value of the attribute.
- Enable search within the values of this attribute (known as search for facet values).
Search for facet values deals with facets configuration in the search relevance retrieval aspect. To configure facets in your user interface, see the facet display guide.
What’s a facet?
Faceted search is a way of classifying records, allowing users to narrow down results. Facets correspond to those taxonomies, which let users refine results by multiple dimensions at a time.
For a book index, facets can be author or genre. For a luxury shop, they can be brands or designers. You can think of facets as filterable categories. Algolia derives these facets from attributes.
Difference between filters and facets
Filters and facets often get mixed up because there’s much overlap, but understanding the difference is essential. Both help to restrict a search to a subset of results.
- Filters provide basic options to help narrow down search results. Sometimes users don’t see the filter restrictions, for example, when automatically filtering to the records they’re allowed to see based on their user ID.
- Facets offer categories to help users refine their search using several complex dimensions at a time. Faceting is still filtering but uses facets to allow users to choose from a set of useful values, features, and counts.
Declaring attributes for faceting
To make an attribute filterable or “facetable”, you must add it to your attributesForFaceting
list. Do this either in the dashboard or through the API.
For example, if you wanted to make your genre
and author
attributes available for both faceting and filtering, you’d need to apply the following setting:
1
2
3
4
5
6
$index->setSettings([
'attributesForFaceting' => [
"genre",
"author"
]
]);
The example shows you how to filter on genre
or author
, and also lists all possible values for each attribute. You could display these on your search UI, so that users can select them.
To use the attributes just for filtering, use the filterOnly
modifier:
1
2
3
4
5
$index->setSettings([
'attributesForFaceting' => [
"filterOnly(author)"
]
]);
Filter-only attributes are helpful when you don’t need to offer a choice to the user. For example, in a book collection, you have one page per author and want to automatically filter results based on the page the user is visiting. It also improves performance because the engine doesn’t need to compile facet counts.
You shouldn’t include colons (:
) in attribute names that you want to use for faceting, because the filters
syntax relies on that character as a delimiter.
Retrieving facets
To retrieve facets and their respective counts as part of the JSON response, you must specify a list of facets in the facets
parameter at query time.
For example, you can retrieve your books’ facets by specifying the following list:
1
2
3
$results = $index->search('query', [
'facets' => ['author', 'genre']
]);
To extract all facet information, you can use a wildcard (*
).
1
2
3
$results = $index->search('query', [
'facets' => ['*']
]);
When the facets
parameter is empty, the engine returns no facet information.
Faceting types and features
Conjunctive and disjunctive faceting
Facet filtering, filtering based on facet values, is a helpful feature for users since it allows them to find specific, targeted results in a way that isn’t possible with one-size-fits-all filters.
You can combine facet filters with AND
(conjunctive) and OR
(disjunctive) operators. When using these operators, the engine handles the facet counts differently to keep a consistent user experience. This doesn’t happen at the API level, but in the InstantSearch libraries.
Hierarchical facets
You can build a hierarchy in your facet values to enable multi-level navigation and filtering. This pattern is interesting to improve discoverability when you have deeply nested categories, as your users can browse up and down in the levels to refine their search.
For example, imagine a book available in Books > Science Fiction > Time Travel:
1
2
3
4
5
"categories": {
"lvl0": "Books",
"lvl1": "Books > Science Fiction",
"lvl2": "Books > Science Fiction > Time Travel"
}
Or a book available in both Books > Science Fiction > Time Travel and Books > Literature & Fiction > Modernism:
1
2
3
4
5
"categories": {
"lvl0": "Books",
"lvl1": ["Books > Science Fiction", "Books > Literature & Fiction"],
"lvl2": ["Books > Science Fiction > Time Travel", "Books > Literature & Fiction > Modernism "]
}
The hierarchicalMenu
widget from the InstantSearch libraries helps you to build hierarchical faceting.
- Disjunctive faceting with hierarchical facets isn’t yet possible.
- Using hierarchical facets with many nested attributes creates many different facet names. This adds a lot of metadata which needs to be processed. That can lead to poor search performance, even if you don’t reference those facets directly.
Contextual facet values and counts
Enabling faceting on attributes computes facet counts for each facet value, and the engine updates and returns the list of values and counts with each search result. It’s helpful to offer users a relevant and contextual set of filters and information.
How the engine approximates facet counts
When dealing with massive indices, the engine might need to approximate facet counts to guarantee optimal performance. If you want to know whether the facet counts are exact, you can check the exhaustiveFacetsCount
property in the JSON response.
Increasing the default limit
By default, the engine lets you retrieve 100 values per facet. If you need to increase this limit, you can use the maxValuesPerFacet
parameter. The maximum is 1000 facet values at a time.
1
2
3
$index->setSettings([
'maxValuesPerFacet' => 1000
]);
Faceting on objectID
You can’t facet on the objectID
attribute, and the engine ignores it if you declare it in attributesForFaceting
. Faceting on a unique identifier makes little sense, though, because every facet count would be equal to one.
The engine treats the objectID
attribute as a filter-only facet. You can filter on that attribute (even without declaring it in attributesForFaceting
), but not get any facet counts.
Attributes are case-sensitive
The attribute names you declare in attributesForFaceting
are case-sensitive: they must exactly match the attribute names in your records. The facetFilters
and filters
parameters are only case-insensitive for values.
For example, if your records include an attribute named color
, with values such as “blue”, “red”, and “green”, you must declare color
(not Color
) within your attributesForFaceting
. You can, however, facet and filter using color:BLUE,
color:Blue, or
color:blue`.
As an exception, facetFilters
and filters
are case-sensitive when filtering on objectID
. For example, objectID:abc
only returns the record with that specific objectID
, not one with objectID:ABC
.
Search for facet values
Sometimes you may have thousands of different values for a given facet attribute, and it would be impossible to display them all on the UI. Instead, you can leverage search_for_facet_values
to let users search within a specific faceted attribute (for example, brands
, authors
, or categories
) without needing to create a separate index. It means that you can still display the first, most common values for each facet, but also let the user search for more.
By default, returned facet values are sorted by count.
Facet queries only match prefixes, typos, and exact.
Declaring a searchable attribute for faceting
You can make a facet searchable on the dashboard (in the Configuration tab of the target index), or with the API:
1
2
3
4
5
$index->setSettings([
'attributesForFaceting' => [
"searchable(author)"
]
]);
Searching in facet values
In this example, the engine would return all the authors matching the query “stephen”.
1
$index->searchForFacetValues("author", "stephen");
Increasing the default limit
By default, you retrieve 10 facet values at a time. You can raise this limit up to 100 by updating the maxFacetHits
parameter.
1
2
3
$index->setSettings([
'maxFacetHits' => 100
]);