Facets are used to create categories on a select group of attributes. For example, on an index of books, useful facets might be author and genre. Additionally, Algolia calculates the count of records for each facet. Thereafter, facets and facet counts can be displayed on the UI, to give users the ability to filter results (e.g. by author or genre).

Faceting is a common search feature that Algolia provides out of the box. In order to leverage faceting, you will need to enable this feature on a per-attribute basis via the attributesForFaceting parameter. Once enabled, it will allow 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 for each value (number of records matching each value of the attribute)
  • Enable search within the values of this attribute (see search for facet values)

Difference between filtering and faceting

These 2 features are often confused because there is much overlap between them, but understanding the difference is important. In general, both are used for restricting search to a subset of results. There may be cases where this is done entirely hidden to the end user - this is done using filters. In contrast, faceting is generally used for building a UI, where users can select facets (as categories) to further refine their query.

Practically speaking, facets need to be first set up as filters before they can be used later as facets. The difference begins there: facets go further than filters by offering features such as listing all values, facet counts, and search for facet values.

Declaring Attributes for Faceting

In order to make a string attribute filterable or facetable, you will 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 category and author attribute available for both faceting and filtering, you would need to apply the following setting:

1
2
3
index.setSettings({
  'attributesForFaceting': ['category', 'author']
})

If you will only be using the attribute for filtering and not faceting, you can specify this to the engine via a filterOnly() wrapper.

1
2
3
index.setSettings({
  'attributesForFaceting': ['filterOnly(category)', 'filterOnly(author)']
})

Using filterOnly() will improve performance, but it will not allow you to use the benefits of facet counts as described below.

You should not include colons (:) in attribute names that you want to use for faceting, because the filters syntax relies on that character as a delimiter.

The same attribute can be used for both faceting AND search at the same time.

Retrieving Facets

In order to retrieve facets and their respective counts as part of the JSON response, you will 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
index.search({
  facets: ['author', 'categories', 'publisher']
});

To extract all facet information, you can use the special value asterisk (*).

1
2
3
index.search({
  facets: ['*']
});

Note that if this parameter is empty, no facet information will be retrieved.

Faceting Types and Features

Conjunctive and disjunctive faceting

From a UI point of view, faceting is often used to filter results (we call it facet filtering). You can combine filters between facets with AND (conjunctive) and OR (disjunctive) operators. When using these operators, the facet counts are handled differently to keep the user experience consistent. This is not implemented at the API level but rather in our search libraries.

Hierarchical facets

You can build a hierarchy in your facet values to enable multi-level navigation and filtering. This pattern is great for very long lists of values and to improve discoverability: your users will be able to browse up and down in the levels to refine their searches.

For 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"
}

For 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, Algolia offers a hierarchicalMenu widget as part of its Instantsearch.js library.

It is currently not possible to do disjunctive faceting with hierarchical facets.

Contextual facet values and counts

As mentioned at the top of this page, enabling faceting on attributes will compute facet counts for each facet value, and the list of values + counts is updated and returned with each search result. This ensures the user always gets a relevant and contextual set of filters and information along with the results.

Approximation

In the case of very large indices, Algolia’s engine might need to do an approximation on facet counts to guarantee optimal performance. If you want to know if the facet counts are exact, you can check the boolean exhaustiveFacetsCount value in the search result’s response.

Increasing the default limit

By default, the engine allows you to retrieve 100 values per facet. In the event you need to increase this limit, you will need to leverage the maxValuesPerFacet parameter. This value can be raised up to 1000.

1
2
3
index.setSettings({
  'maxValuesPerFacet': 1000
})

Faceting on objectId

You cannot facet on the objectID attribute. If objectID is declared in attributesForFaceting, it will be ignored. Faceting on a unique identifier makes little sense anyway, since every facet count would be equal to one.

However, objectID is implicitly treated as a filter-only facet: you can specify a facet filter on that attribute (even if it’s not listed in attributesForFaceting), but you will never get any facet counts.

Case Sensitivity

Facets and facet filters are case-insensitive, except for facet filters on objectIds, which are case-sensitive.

Search for Facet Values

How it works

Sometimes you have thousands of different values for a given facet attribute and it is impossible to display all of them on the user’s interface.

With Search for facet values, you can allow your users to search within a specific faceted attribute (for example, brands, authors, or categories) without needing to create a separate index. This means that you can still display first the most common occurrences for each facet, but also enable the user to search for a specific value to use for filtering. By default, facet values are returned sorted by their count.

Declaring a searchable attribute for faceting

You can make a facet searchable through the dashboard (in the Configuration tab of the target index), or through the API:

1
2
3
index.setSettings({
  'attributesForFaceting': ['searchable(author)', 'categories', 'publisher']
})

Searching in facet values

In this example, all the categories containing a match to the query ‘phone’ would be returned.

1
2
3
4
index.searchForFacetValues({
  facetName: 'category',
  facetQuery: 'phone'
})

Increasing the default limit

Out-of-the-box, you will only be able to 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
})

Did you find this page helpful?