Guides / Managing results / Rules / Detecting intent

Dynamic Filtering with Rules

You can use Rules to add filters dynamically depending on what the user types.

Filter by color

Consider the query “red t-shirt”. A customer wants Algolia to recognize “red” as a color and therefore restrict the search only to records containing “red” in their color attribute whenever the keyword “red” is typed in.

Rule

If query contains ‘red’ then filter by color=red

Option 1 - Using filters

API

One approach is to use the filters parameter. With this approach, you will need to have 1 Rule per filter value. So if you have 10 color options, you will need to create 10 Rules, 1 for each color.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$rule = array(
  'objectID' => 'red-color',
  'condition' => array(
    'pattern' => 'red',
    'anchoring' => 'contains'
  ),
  'consequence' => array(
    'params' => array(
      'query' => array(
        'remove' => 'red'
      ),
      'filters' => 'color:red'
    )
  )
);

// push Rule to index
$index->saveRule($rule['objectID'], $rule);

Dashboard

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Type “red” in the input field and press Enter.
  • In the Consequences section:
    • Click the Add consequence button and select Add Query Parameter.
    • In the Custom JSON Data panel that shows up, add the data to return when the user query matches the Rule: {"filters":"color:red"}
    • Click the Add consequence button and select Remove Word.
    • Type “red” in the input field and press Enter.
  • Click Save.

Option 2: Using facets

This alternative method is only available through our Premium plans.

API

This approach uses facets. With facets, instead of creating 1 Rule for each color, you create 1 Rule per facet. So if you have the facet ‘color’, then 1 Rule will handle every color value. For example, if the query includes red, and if red matches a value in the color facet, the Rule will be triggered.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// turn json into an array
$rule = array(
  'objectID' => 'color-facets',
  'condition' => array(
    'objectID' => 'color-facets',
    'pattern' => '{facet:color}'
  ),
  'consequence' => array(
    'params' => array(
      'automaticFacetFilters' => ['color']
    )
  )
);

// push Rule to index
$index->saveRule($rule['objectID'], $rule);

You can replace automaticFacetFilters with automaticOptionalFacetFilters, they share the same syntax. This includes non-red t-shirts below the red ones. Learn more about optionalFilters.

Dashboard (facets)

This alternative method is only available through our Premium plans.

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Click in the input and select the option Add Facet “color” in the dropdown.{facet:color} should then be displayed in the input.
  • In the Consequences section:
    • Click the Add consequence button and select Filter / Boost Matching Attributes.
    • In the Filter input that shows up, select the option Add Facet “color” in the dropdown.
  • Click Save.

Filter by type

Show only “shirts” whenever the engine detected a kind of shirt like “t-shirt”.

Rule

If query contains ‘t-shirt’ then filter by type=shirt

API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// turn json into an array
$rule = array(
  'objectID' => 't-shirt',
  'condition' => array(
    'pattern' => 't-shirt',
    'anchoring' => 'contains'
  ),
  'consequence' => array(
    'params' => array(
      'query' => array(
        'remove' => 't-shirt'
      ),
      'filters' => 'clothing_type:shirt'
    )
  )
);

// push Rule to index
$index->saveRule($rule['objectID'], $rule);

Dashboard

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Type “t-shirt” in the input field and press Enter.
  • In the Consequences section:
    • Click the Add consequence button and select Add Query Parameter.
    • In the Custom JSON Data panel that shows up, add the data to return when the user query matches the Rule: {"filters":"clothing_type:shirt"}
    • Click the Add consequence button and select Remove Word.
    • Type “t-shirt” in the input field and press Enter.
  • Click Save.

Numerical filtering

Imagine the query “cheap toaster 800w”. Rules can be used to filter the results by “toaster” and “prices between 0 and 25”, so that the only textual search is the remaining term, “800w”, which could further be used to limit the results with that wattage.

Rule

If query = “cheap toaster” then price < 10 and type=toaster

Note: This requires 2 Rules.

API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// turn json into an array
$rules = array(
  array(
    'objectID' => 'toaster',
    'condition' => array(
      'pattern' => 'toaster',
      'anchoring' => 'contains'
    ),
    'consequence' => array(
      'params' => array(
        'query' => array(
          'remove' => 'toaster'
        ),
        'filters' => 'product_type:toaster'
      )
    )
  ),
  array(
    'objectID' => 'cheap',
    'condition' => array(
      'pattern' => 'cheap',
      'anchoring' => 'contains'
    ),
    'consequence' => array(
      'params' => array(
        'query' => array(
          'remove' => 'cheap'
        ),
        'filters' => 'price < 10'
      )
    )
  )
);

// push Rule to index
$index->batchRules($rules);

Dashboard

Create the first rule:

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Type “toaster” in the input field and press Enter.
  • In the Consequences section:
    • Click the Add consequence button and select Add Query Parameter.
    • In the Custom JSON Data panel that shows up, add the data to return when the user query matches the Rule: {"filters":"product_type:toaster"}
    • Click the Add consequence button and select Remove Word.
    • Type “toaster” in the input field and press Enter.
  • Click Save.

Then the second rule:

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Type “cheap” in the input field and press Enter.
  • In the Consequences section:
    • Click the Add consequence button and select Add Query Parameter.
    • In the Custom JSON Data panel that shows up, add the data to return when the user query matches the Rule: {"filters":"price < 10"}
    • Click the Add consequence button and select Remove Word.
    • Type “cheap” in the input field and press Enter.
  • Click Save.

Tagged filters

One interesting pattern you can leverage with Rules is tagged filters. Instead of automatically filtering when a search term matches a facet value, tagged filters let users apply filters with prefixes. For example, you could imagine a query like “headphones brand:apple”, which would search for results that match the term “headphones”, but only where the brand attribute matches “apple”.

You can find this behavior on applications such as GitHub or Slack. They provide great alternative to refinement lists for users who prefer to type rather than click.

Rule

If query contains “brand:apple” then filter on brand=Apple

This feature is only available to Premium plans.

API

This approach uses facets. With facets, instead of creating a Rule for each facet value, you create one Rule per facet. For example, we can create a Rule for the facet brand, which handles all our facet values for the brand facet. This way, our Rule will activate if our query contains “Apple”, if you have at least one record with “Apple” in the brand attribute.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
$rule = array (
  'conditions' => array(
  array (
    'pattern' => 'brand\\: {facet:brand}',
    'anchoring' => 'contains',
    'alternatives' => false,
  )),
  'consequences' =>
  array (
    array (
      'params' =>
      array (
        'automaticFacetFilters' =>
        array (
          'brand',
        ),
        'query' =>
        array (
          'remove' =>
          array (
            'brand\\:',
            '{facet:brand}',
          ),
        ),
      ),
    ),
  ),
  'description' => 'filter on brand: {brand}',
  'objectID' => 'tagged-brand-rule',
);

$response = $index->saveRule($rule['objectID'], $rule);

You can replace automaticFacetFilters with automaticOptionalFacetFilters, they share the same syntax. This includes non-Apple items below the Apple ones. Learn more about optionalFilters.

Dashboard

  • Go to your dashboard and select your index.
  • Click the Rules tab.
  • Click the New Rule button.
  • In the dropdown, click on the Manual Editor option.
  • In the Condition section:
    • In the If the query… input field, set the anchoring to Contains.
    • Click in the input and type brand: {facet:brand} manually
    • Uncheck the Apply to plurals, synonyms and typos checkbox.
  • In the Consequences section:
    • Click the Add consequence button and select Filter / Boost Matching Attributes.
    • In the Filter input that shows up, select the option Add Facet “brand” in the dropdown.
  • In the Consequences section:
    • Click the Add consequence button and select Remove word.
    • In the Filter input that shows up, enter brand: {facet:brand}.
  • Click Save.

Did you find this page helpful?