Icon searching white

Faceting

Last updated 17 October 2017

Faceting overview

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 filtering, you would need to apply the following setting:

index.set_settings({
  '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.

index.set_settings({
  '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.

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:

index.search({
  facets: ['author', 'categories', 'publisher']
});

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

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.

Interesting hierarchical categories for books (simplified here for the purpose of the example): { hierarchical_categories: 'Books > Science Fiction > Time Travel' } { hierarchical_categories: 'Books > Science Fiction > Galactic Empire' } { hierarchical_categories: 'Books > Literature & Fiction > Classics' }

To build hierarchical faceting, it is recommended to use Algolia’s Instantsearch.js library which has a widget to accomplish this out of the box.

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.

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 either make a facet searchable from the dashboard (“Display” tab of the index), or through the API:

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.

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.

index.setSettings({
  'maxFacetHits': 100
})

UI Patterns

Here are a few UI patterns we recommend for building search experiences that include faceting.

Instant Search Result Page

Algolia’s instansearch library offers a set of components that are unified with a shared context of search, meaning that any interaction with one widget will update the others accordingly to always have an accurate and relevant context. It’s an important feature that enables users to leverage filters and facets to easily drill down to the content most relevant to them.

Web

Traditionally, filters and facets are displayed on the left side of the search result page, with the search bar on top and the results on the right. This is a really effective way to organize the different search components since it is familiar for most users and it makes everything accessible easily. In some specific domains, like blogs, filters and results can be reversed.

Mobile

Building a good instant search experience on mobile is more challenging. The pattern we recommend the most is to create a hidden panel with all the filters and facet options. Once the user clicks the “filter” or “refinement” button, this panel would display. It is important to provide feedback and let the user know that each action has been applied and produced a new set of results, so there are 2 possibilities:

  • without hiding completely the search results: the user sees results being updated
  • full-screen panel hiding the search results: you can display the number of expected results each time a filter is applied, for example in the “close” or “validate” button.

Search for Facet Values

Beyond the basic use case of allowing users to search within provided facets (for example, brands), search for facet values can be leveraged to power associated tags and build an advanced “guided search” experience, similar to Pinterest. To accomplish this, you simply need to pass in an existing facet value as a “facet” as part of your “searchForFacetValues” query.

What’s Next

Continue building your Algolia knowledge with these concepts:

You might also be interested in this tutorial:

© Algolia - Privacy Policy