Faceting
On this page
Facets let you create categories on a select group of attributes, so your end users can refine their search. For example, on an index of books, useful facets might be author and genre. Additionally, Algolia calculates how many results there are for each facet. It allows you to display facets and facet counts on the UI for the user to filter down results (e.g., 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 the 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).
What is 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. In the context of Algolia, we derive these facets from attributes.
Difference between filtering and faceting
Filtering and faceting often get mixed up because there’s much overlap between them, but understanding the difference is essential. In general, both help to restrict a search to a subset of results. There are cases where the end user doesn’t see these restrictions at all, for example, when automatically filtering to the records they’re allowed to see based on their user ID. In contrast, faceting is useful when building a UI, where users can select facets categories to refine their search further.
Practically speaking, you always use filtering to narrow down search results. Faceting is a subset filtering: it goes further by providing users with a list of all the values features, counts, and search for facet values. They can narrow down results by several complex dimensions at a time.
Declaring attributes for faceting
To make an attribute filterable or facetable, you need to add the attribute to your attributesForFaceting
list. You can 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"
]
]);
Here, you would not only be able to filter based on genre
or author
, but you would also get a list of all the possible values for each attribute. You could display these on your search UI, allowing your end users to select them.
To use the attributes for filtering only, you can use the filterOnly
modifier:
1
2
3
4
5
$index->setSettings([
'attributesForFaceting' => [
"filterOnly(author)"
]
]);
Filter-only attributes are useful when you don’t need to offer a choice to the end user. For example, if you had one page per author and wanted to automatically filter on it based on what page the user is visiting. It also improves performance because the engine doesn’t need to compile the 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 need to 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
From a UI perspective, faceting is useful to filter results. We call this facet filtering, which means filtering based on facet values.
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 our InstantSearch UI 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 "]
}
To help you build hierarchical faceting, we provide a hierarchicalMenu
widget in our Instantsearch UI libraries.
You currently cannot do disjunctive faceting with hierarchical facets.
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 useful to provide the end user with a relevant and contextual set of filters and information.
Approximative facet counts
When dealing with massive indices, the engine might need to make an approximation on 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 1,000 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.
However, the engine implicitly treats the objectID
attribute as a filter-only facet. You can filter on that attribute (even without declaring it in attributesForFaceting
), but don’t get any facet counts.
Case sensitivity
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 case-insensitive for values only.
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
returns only 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 (e.g., 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, we return facet values sorted by count.
Declaring a searchable attribute for faceting
You can make a facet searchable via 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 containing a match to the query “stephen”.
1
$index->searchForFacetValues("author", "stephen");
Increasing the default limit
By default, you can only 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
]);