05 Oct 2018



The ideal of modern search is smart search — highly relevant results, tuned specifically for each user. For example, judo experts searching for judo techniques might be interested in advanced techniques while beginners would want to learn how to get started. Teenagers searching for “Grand Theft Auto” might be looking for game strategies while their parents would want to know if the game is appropriate for their kids.

Some more concrete examples from everyday products:

  • On Netflix, prioritize movies in my watch list
  • On Asana, prioritize tasks assigned to me
  • On Amazon, prioritize products in my typical price range, or from brands I’ve previously purchased

While users can certainly create advanced queries to narrow down exactly what they’re looking for, why should they have to? Above are just a few examples in which knowing a bit of information about a user can radically improve the relevance of their search results.

Personalization, using optionalFilters, is available without limit on the Business and Enterprise plans. Other plans are limited to one optional filter per query. See our pricing page.

Live Demo

We built a demo showcasing personalization on a search for movies.

Personalization Query Parameters

This guide explains how to use two features, optional filters and filter-scoring, to achieve personalized ranking strategies.

Optional Filters

Optional filters are not available on legacy plans (Starter, Growth, Pro). If you are on one of these plans and want to benefit from this feature, you will need to move to a new plan. Furthermore, Community, Essential, and Plus plans are limited to only one optionalFilters per query, while Business and Enterprise plans are unlimited.

You may already be familiar with the filters search parameter. We now introduce a new search parameter, optionalFilters. Optional filters behave much like regular filters, except that results not matching the filter are not excluded altogether; they’re only ranked lower in the result set.

For example, if you know a user is interested in the brand “samsung”, you can personalize the query with optionalFilters:

algolia.search("phone", { optionalFilters: ["brand:samsung"] });

Phones from Samsung will be returned first, followed by other phones.

Optional Filters can be applied on any attribute declared in attributesForFaceting.

For performance reasons, filter scoring should not be used on searches that may return more than 100,000 results.

Scoring with OptionalFilters

As described above, optional filters only divide records into two sets:

  • those matching the optional filter
  • all the rest

Filter scoring is a way to create a more nuanced ranking, by specifying different scores for different filters. For example, consider a scenario in which a user prefers the following ranking:

  • Apple products should be returned first
  • Samsung products should be returned next
  • All other products should be returned last

The query could be personalized by giving each filter a score:

algolia.search("phone", {
  optionalFilters: ["brand:apple<score=2>", "brand:samsung<score=1>"]

Scoring with Filters and Facets

As opposed to Optional filters, filter scoring is fully available under all plans.

Filter scoring can also be used with filters and facetFilters. Note that filter and facet scoring only works with OR conditions.

algolia.search("phone", {
  filters: "brand:apple<score=2> OR brand:samsung<score=1>"]
algolia.search("phone", {
  facetFilters: [
    ["brand:apple<score=2>", "brand:samsung<score=1>"]

Both OptionalFilter and Filter scoring should not be used on searches that may return more than 100,000 results.

Personalization’s Impact on Ranking

Both the optional filters and the filter scoring rely on a dedicated rule in the Ranking Formula, called filters.

By default, this rule is placed in the fourth position — after typo, geo, and words. We recommend leaving these as the defaults in the majority of use cases.

How the scores are calculated

The calculation of the total score, which will be used in the filters rule of the above Ranking Formula, follows two rules:

  • When no score is specified, it defaults to 1
  • When you specify scores on multiple filters, the global score is equal to the highest score of the matched filters

Consider these two examples:

optionalFilters = ["brand:Apple", "brand:Samsung<score=2>"]
/* Will rank results in this order:
1. Samsung (score = 2)
2. Apple (score = 1)
3. other brands (score = 0) */

optionalFilters = ["brand:Apple", "brand:Samsung<score=2>", "users:user42<score=3>"]
/* Will rank results in this order:
1. Samsung and user42 (score = 3)
2. Apple and user42 (score = 3)
3. other brands and user42 (score = 3)
4. Samsung, no match on user42 (score = 2)
5. Apple, no match on user42 (score = 1)
6. other results (score = 0) */

Sum OR Scores

As described above, optionalFilters considers only the highest scoring matched filter. However, this behavior can be changed with sumOrFiltersScores. Applied at query-time, this parameter tells the engine to sum the scores of matched filters instead of only taking the highest scoring match. With sumOrFiltersScores applied, the above scoring would now be a bit different:

optionalFilters = ["brand:Apple", "brand:Samsung<score=2>", "users:user42<score=3>"]
/* Will rank results in this order:
1. Samsung and user42 (score = 5)
2. Apple and user42 (score = 4)
3. other brands and user42 (score = 3)
4. Samsung, no match on user42 (score = 2)
5. Apple, no match on user42 (score = 1)
6. other results (score = 0) */


These features, while powerful, come with some important limitations, particularly in terms of performance. Here are a few recommendations:

  • Define optionalFilters with the filterOnly() modifier, which tells the engine to treat the attribute as a simple filter instead of a facet. For example:
  attributesForFaceting: [
  • Aim for low cardinality on attributes being used for optionalFilters. For example, brand would typically be preferable to product; there may be an order of magnitude more products than brands.
  • Try to minimize the number of applied filters.
  • Aim for queries to return a smaller result set.
  • Finally, talk to us — we can apply sharding and other custom settings to optimize for your use case :)
© Algolia - Privacy Policy