Guides / Managing results / Rules / Merchandising and promoting items

Optional Filters

Filters don’t have to be exclusive. They don’t only remove records that don’t match the filter values. Sometimes, you may want to use filters in a way that only favors or disfavors records that match with those that don’t match a filter.

For example, if someone uses the term “hungry” in their search query and clicks on the “deliver quickly” facet, you may interpret this as them looking for restaurants that can deliver as quickly as possible. Yet, you wouldn’t necessarily want to filter out other restaurants, especially if most of them can’t deliver right away. You can achieve this with Algolia’s optionalFilters feature.

For all legacy plans (Community, Essential, Plus, signed up before December 15, 2018), optional filters are limited to only one per query.

Imagine you have the following dataset:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
[
  {
    "name": "Pasta Bolognese",
    "restaurant": "Millbrook Deli",
    "delivery_waiting_time": 20,
    "popularity": 80
  },
  {
    "name": "Pasta Bolognese",
    "restaurant": "The Hive",
    "delivery_waiting_time": 15,
    "popularity": 80
  },
  {
    "name": "Pasta Bolognese",
    "restaurant": "Bert's Inn",
    "delivery_waiting_time": 40,
    "popularity": 90
  }
]

Let’s say you have set descending custom ranking on popularity, and ascending custom ranking on delivery_waiting_time. If a user searches for “pasta bolognese”, the first result would be “Bert’s Inn”, because it has higher popularity. Then you would have “The Hive” and “Millbrook Deli” because they have the same popularity, so the engine would move on to delivery_waiting_time to tie break. The top result would, therefore, be the most popular one, not necessarily the one that can deliver as fast as possible.

To push the records that can deliver quickly first, regardless of the custom ranking, we can use optional filters. The optionalFilters parameter only applies on exact matches, you can’t do numeric comparisons like with filters. Therefore, you need to alter your dataset so you can match on exact values.

For example, if you think that a waiting time of 20 minutes or less is quick enough, you could create an attribute can_deliver_quickly and set it to true for each record that has a delivery_waiting_time of “20” or less.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[
  {
    "name": "Pasta Bolognese",
    "restaurant": "Millbrook Deli",
    "delivery_waiting_time": 20,
    "can_deliver_quickly": true,
    "popularity": 80
  },
  {
    "name": "Pasta Bolognese",
    "restaurant": "The Hive",
    "delivery_waiting_time": 15,
    "can_deliver_quickly": true,
    "popularity": 80
  },
  {
    "name": "Pasta Bolognese",
    "restaurant": "Bert's Inn",
    "delivery_waiting_time": 40,
    "can_deliver_quickly": false,
    "popularity": 90
  }
]

When users click on the “deliver quickly” facet, you want to automatically boost every record in which can_deliver_quickly is equal to true. To do so, you first need to set can_deliver_quickly in your list of attributes for faceting. Then you would create an optional filter with can_deliver_quickly=true.

Let’s assume your user has left a bad review for one of the restaurants, Bert’s Inn. We may want to push this item to the bottom of the list, so that it’s still available to the user, but the results are more relevant. You can do this with a negative optional filter on the restaurant’s name.

Using the API

First, you need to set can_deliver_quickly and restaurant as attributesForFaceting. This happens at indexing time.

1
2
3
4
5
6
$index->setSettings([
  'attributesForFaceting' => [
    "can_deliver_quickly",
    "restaurant"
  ]
]);

Then, you can send the optional filters with your query.

1
2
3
4
5
$results = $index->search("hungry", [
  'optionalFilters' => [
    "can_deliver_quickly:true"
  ]
]);

If you want to disfavor a specific restaurant, you can add a negative optional filter on the restaurant attribute.

1
2
3
4
5
$results = $index->search("hungry", [
  'optionalFilters' => [
    "restaurant:-Bert's Inn"
  ]
]);

Using the Dashboard

You can set your attribute to be used for faceting in your Algolia dashboard:

  1. Go to your dashboard and select your index.
  2. Click the Configuration tab.
  3. In the Facets subsection of Filtering and Faceting, click the “Add an attribute” button and select the can_deliver_quickly attribute from the dropdown.
  4. Don’t forget to save your changes!

Regarding filters (or optional filters), you can’t set them to be applied directly in the dashboard since you can only filter at query time. However, you can test filters and optional filters in the dashboard before using them in your search code.

  1. Go to your dashboard and select your index.
  2. Click the Add Query Parameter button, which is just below the search bar.
  3. Go to the Custom tab.
  4. Add your filter as JSON: { "optionalFilters": "can_deliver_quickly:true" }.
  5. Click Apply.

Note that you can alternatively use facet filters. Click the Add Query Parameter button, go to the Filters tab and enter your targeted facet filter(s).

Did you find this page helpful?