> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Implement rules

> Learn how to add index rules to curate your search results.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

export const Index = () => <Tooltip tip="An Algolia index is a searchable dataset that consists of records and configuration settings. These settings define how the records are searched and ranked.">
    index
  </Tooltip>;

export const Filter = () => <Tooltip tip="A filter is a condition that limits which records Algolia returns. Filters often use one or more facet-value pairs, such as brand:Apple AND color:red. You can also filter by numeric values, dates, tags, booleans, or geographic constraints." cta="Filtering" href="/doc/guides/managing-results/refine-results/faceting">
    filter
  </Tooltip>;

**Use the dashboard to familiarize yourself with rules**.
The dashboard provides a responsive interface to create and configure your rules.
And importantly, test your choices using the dashboard's live search interface.

You may never need to go beyond the dashboard if your rules are manageable in the UI or follow a defined pattern.

In this way, you can consider the dashboard as a way to manage static rules—rules that remain in place for some time or whose effect is global and constant.

Open the **Rules** page for a selected <Index /> and click **Add Rule**.
You can choose between two editors:

* The **Visual Editor** lets you pin results and hide results, boost categories, and <Filter /> results through a visual, guided user journey.
* The **Manual Editor** supports more options but doesn't offer an instant preview of the results.

## Coding rules with the API clients

Coding rules using the Rules API becomes necessary when you need more programmatic control.
This move from static to more dynamic rules can arise for several reasons—like when you can't manage rules one-by-one or when you want to start building (and deleting) rules based on the content of your database.
You should use the API if your rules change with every new update of your index or if you offer a frontend to manage your rules.

You must set up your index for the API and then set up the rules at indexing time.

## How index rules works

**Algolia adapts its behavior according to a rule's consequences**.
Rules are if-then configurations or condition/consequence pairs:
the consequence applies to the returned results if the condition is satisfied.
For example, a rule with the condition "user's query contains the word red" and the consequence "filter on the facet color:red".

And that's only one kind of consequence.
As described in the overview and presented in technical detail below—
Different kinds of consequences adapt the search and alter the relevance.

Rules are processed at indexing time to prepare the index so that when someone performs a search,
the data is ready for the if-then matching.

Keep in mind:

* If the `alternatives` setting of a rule is `false`, the condition must match the entire word (as a whole word) for the rule to be triggered.
* All text matching is case insensitive.
* Conditions can match on multiple phrases.
* A rule can have multiple conditions and multiple consequences.

<Info>
  Rules have no noticeable impact on search performance.
  Most of the work happens during indexing.
</Info>

## Turning rules on and off

Turn a rule off by setting its `enabled` flag to `false`.
Rules that have been turned off remain in the index.
They're still searchable, but ignored at query time.
This is an alternative to deleting a rule when you wish to turn it off temporarily.

For even more fine-grained control,
you can specify **validity windows** on rules (with the `validity` attribute).
Rules with validity windows only apply during the specified time frames:
they're ignored the rest of the time.
Rules with no time windows always apply.
Like with the `enabled` flag, rules with validity windows remain searchable all the time.

## API overview

### Pre-processing and post-processing

As suggested, rules allow fine-tuning results for queries matching specific patterns.
They do so in two complementary ways:

1. **Query pre-processing.**
   Rules may alter the query parameters—not only the query string but also features such filters and facets—before the query is processed.

2. **Results post-processing.**
   Rules might cause results (hits) to be ranked differently for specific queries.
   They can also add user data to the results.

Rules are complementary to the traditional ranking and textual relevance settings:
while settings act globally on every search to an index, rules act selectively.

### Conditions and consequences

The general syntax is as follows:

```jsonc JSON icon=braces theme={"system"}
{
    "conditions": [
        { 
            // What the query must match for the rule to be applied.
        },
    ],
    "consequence": { 
        // How the query will be modified if the rule is applied. 
    }
}
```

#### Condition: what the query must match

Conditions identify query strings matching a specific pattern.
If the query string matches all the rule's conditions,
it activates the rule for that search.

More precisely, a condition consists of:

* An optional **query pattern** acting on the whole text query string, that is, the `query` search parameter.
* Optional **anchoring** defining how the rule's query pattern compares to user queries.
* Optional **filters**, which must match the filters applied with the query. These can be [`filters`](/doc/api-reference/api-parameters/filters) or [`facetFilters`](/doc/api-reference/api-parameters/facetFilters), but not [`numericFilters`](/doc/api-reference/api-parameters/numericFilters), [`tagFilters`](/doc/api-reference/api-parameters/tagFilters), nor [`optionalFilters`](/doc/api-reference/api-parameters/optionalFilters).
* An optional **context** must match a context supplied at query time with the [`ruleContexts`](/doc/api-reference/api-parameters/ruleContexts) parameter
* Optionally enabled **alternatives**, which indicates whether synonyms and plurals of the query pattern are treated as matches.

#### Consequence: modify the query

A rule's consequence can be one or more actions:

* [Add query parameters](/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/rules-query-parameters)
* [Automatic facet filter](#automatic-facet-filter)
* [Automatic optional facet filter](#automatic-optional-facet-filter)
* [Remove or replace a word from the query string](#remove-or-replace-a-word-from-the-query-string)
* Replace the query string entirely
* Promote or hide specific hits
* Return user data

## Conditions: adapt the query

A rule can have any number of conditions:

* If a rule has no conditions, it applies to every search.
* If a rule has more than one condition, it applies when any condition matches.

For more information about multiple conditions, see [rule structure](/doc/guides/managing-results/rules/rules-overview#conditions)

### Rule query pattern

The query pattern is the most crucial part of the rule's condition.
It consists of a sequence of tokens, treated as a phrase.
All tokens must appear contiguously and in the specified order.

The allowed token types are:

* **Literal**: matches a word.
  The matching is case insensitive.
  If a rule's `alternatives` setting is `true`,
  then matching considers typo tolerance, plurals, and synonyms.
  If you set [`ignorePlurals`](/doc/api-reference/api-parameters/ignorePlurals) to `true` or [`synonyms`](/doc/api-reference/api-parameters/synonyms) to `false`, your `alternatives` setting is ignored.

* **Facet value placeholder**: matches any value of a given facet in the same index.

You must declare the facet in `attributesForFaceting`.
Matching is case insensitive.
Contrary to literals, facet values may be phrases.

The pattern is implicitly a phrase.
The order of words matters: `foo bar` and `bar foo` aren't identical patterns.

The pattern also has an **anchoring type**,
depending on whether its boundaries (beginning, end) must coincide with the boundaries of the query string:

* **starts with**: the pattern must match the words at the beginning of the query string, but there may be extra words at the end
* **ends with**: the pattern must match the words at the end of the query string, but there may be extra words at the beginning
* **contains**: the pattern must match any contiguous sequence of words of the query string.

#### Escape characters within a pattern

To include special characters like colons (`:)`, braces (`{`, `}`), or backslashes (`\`) in a query pattern, you need to escape them.
For example, to match the pattern `thrones:episode`, write it as:

```json JSON icon=braces theme={"system"}
"pattern": "thrones\\:episode"
```

The first backslash escapes the colon for Algolia, and the second is required by JSON syntax.

### Filters can trigger rules

[`filters`](/doc/api-reference/api-parameters/filters) or [`facetFilters`](/doc/api-reference/api-parameters/facetFilters) can trigger rules.
The primary goal of this condition is to create rules that are triggered on specific category pages or when a user applies specific filters.

If a rule's condition has only filters and not query pattern nor context,
Algolia applies the rule's consequences.
Algolia applies the rule's consequences if a condition only has filters:
no query patterns or context.
If a condition also has query patterns or context,
those must match for the rule to be triggered.

<Info>
  To use an attribute in a condition with filters,
  [declare it in `attributesForFaceting`](/doc/guides/managing-results/refine-results/faceting/how-to/declaring-attributes-for-faceting).
</Info>

#### A single rule per filter value

Just like only a single rule can be triggered per word in the query,
only a single rule can be triggered per applied filter. For example:

* Rule A has the filter `brand:Nike` as its condition
* Rule B has the filter `brand:Nike` and the query "shoes" as its condition
* If the query is "shoes" and the filter `brand:Nike` is applied, only rule B is triggered.
* If the query is anything other than "shoes" and the filter `brand:Nike` is applied, only rule A is triggered.

This follows the same [rule matching algorithm](/doc/guides/managing-results/rules/rules-overview/in-depth/rule-matching-algorithm) applied to rules on queries and contexts.

#### Matches must be exact

A rule with filter values in the condition triggers only when the search contains that value just for that filter.
For example, if a rule's condition contains `"filters": "brand:Nike"`,
this rule triggers if **only** the value `Nike` is selected in the filter `brand`.
Algolia doesn't trigger the rule for a query filtered on `brand:Nike OR brand:Supreme`.

If a condition has multiple filters, all applied filters must match the condition with no additional filter values to trigger the rule.
For example, if the rule condition is `"filters": "brand:Nike AND color:red"`,
then Algolia triggers this rule if only the value `Nike` is selected in the `brand` filter and only the value `red` is selected in the `color` filter.
The rule isn't triggered if only `Nike` is selected without `red`,
and it doesn't trigger if `brand:Nike` and `color:red OR color:blue` are selected.

#### Only the filtering attributes in the condition matter

If a rule's condition includes the filter `brand:Nike` and no other filters,
Algolia only considers the `brand` attribute's applied filter values to decide whether to trigger the rule.

For example, if a query filters on `brand:Nike AND color:red`,
that rule doesn't consider the value of the `color` filter because it's not part of the condition.
Algolia triggers the rule since `brand` is filtered on `Nike`.

#### Multiple filtering attributes

If a condition has multiple filters, the following applies:

* Multiple values for the same attribute are grouped with an `OR` condition
* Values for different attributes are grouped with an `AND` condition.

That means Algolia interprets a condition with `brand:Supreme`, `brand:Nike`, `gender:men` as `(brand:Supreme OR brand:Nike) AND (gender:men)`.

In other words, Algolia triggers the rule if a user selects the same set of values (`Supreme`, `Nike` and `men`) in the filters on the frontend.

These conditions only hold if the frontend filters work with the same logic.
For example, if a user filters on `Nike`, `Supreme` for brand, and `red` for color, the filtering logic follows the `AND of ORs` pattern: `(brand:Nike OR brand:Supreme) AND color:red`.
Thus the filters are compatible with filtering conditions possible on rules.

Filters in rules' conditions aren't compatible with `ORs of ANDs`, `ANDs of ANDs` or `ORs of ORs` logic.
For example, consider a real estate search where a user filters for a two-bedroom apartment in Paris with a balcony and fireplace. In this use case, the desired logic would be `ANDs of ANDs`: `bedrooms:2 AND (amenities:balcony AND amenities:fireplace) AND location:Paris`.
You can't create a rule with a condition to match this filtering.

### Context

To narrow, customize, or make rules query-independent,
you can have a rule respond to the [`ruleContexts`](/doc/api-reference/api-parameters/ruleContexts) parameter.

The contexts found in the `ruleContexts` of user searches are compared to the contexts you assign to your rules.

Contexts passed as parameters during your search:
doing so activates all rules that share the context you passed.
**Activation means the rule is considered not to have been applied**.
If your rule's condition only contains a context,
the rules consequence is applied to search results.
If your rule also contains a query pattern,
that pattern must match for the consequence to be applied.

For example, you can define a set of rules with the context "homepage" and pass the same context value along with any search that originates from your homepage. Now you have a set of rules that apply to the homepage search,
giving a more customized experience.

A rule can have one context at most, but a search may have multiple contexts: these are treated as disjunctive (OR).
When one or more contexts are specified at query time, rules matching any of those contexts are activated.

General rules are always activated.

The context's primary goal is to conditionally enable rules for specific search environments.

If present, the context is a string that must be passed at query time in the `ruleContexts` search parameter
with the same value for the rule to be triggered. Matching is case-sensitive.

The `ruleContexts` parameter lets you enable multiple contexts simultaneously.

<Check>
  A rule context must consist only of alphanumeric characters, hyphens, and underscores.
</Check>

## Consequence—adapt the results

A rule's consequence can be one or more actions.

### Add query parameters

Any number of valid search parameters are supported.
These parameters are literals (constants).

This consequence lets you add or modify any search settings that can be changed when the query is sent to Algolia.
Some settings that affect search, like searchable attributes,
can only be modified at indexing time, meaning you can't change them at query time.

[Any parameter](/doc/api-reference/api-parameters) with `search` as part of its scope can be changed at query time.

One common example of a parameter that's useful to change at query time is `filters`.
For example, when someone searches "tablet",
you want to show not only tablets (products with 'tablets' in their `categories` attribute)
but also laptops used as tablets (products with 'hybrids' in their `categories` attribute).
To do this in the dashboard,
click **Add Query Parameter** when adding a consequence for your index rule,
and add the following JSON into the editor:

```json JSON icon=braces theme={"system"}
{
  "filters": "categories:tablets OR categories:hybrids"
}
```

You can also [add filters with the API](/doc/guides/managing-results/rules/detecting-intent/how-to/applying-a-custom-filter-for-a-specific-query#using-the-api).

### Automatic facet filter

Automatically transform a word or group of words into a facet filter if it matches a value in a given facet.
A user enters "red", which is also a value in the color facet. You can set up a rule to transform red to behave like a filter.

Another approach would be to use the filters parameter (using the "add query parameters" rule) but,
with this approach, you must have one rule per filter value.
If you have 10 color values in your color facet,
you must create 10 rules, one for each color.

It's more powerful to use automatic faceting: instead of creating one rule for each color, you create one rule per facet.
Whether users types "blue" or "red", this single rule will apply, it also applies to new colors added to the facet.

When the pattern
matches multiple values of the same facet, filters can be either **conjunctive** (`AND`, default) or **disjunctive** (`OR`). By default, the filters are combined with an `AND` operator. However, if you specify the filter to be
disjunctive, an `OR` operator is used instead. In both cases, relationships to other filters
in the query will always be conjunctive (`AND`).

You can also specify a score for the created filter, mainly useful for optional facet filters (see below).

For example, to automatically filter on the `brand` facet, using `OR` in case of multiple occurrences:

```json JSON icon=braces theme={"system"}
{
  "conditions": [
    {
      "pattern": "{facet:brand}"
    }
  ],
  "consequence": {
    "params": {
      "automaticFacetFilters": [
        {
          "facet": "brand",
          "disjunctive": "true"
        }
      ]
    }
  }
}
```

And if you want to reverse the logic to exclude the captured facet for example, you can use the `negative` field and set it to `true`.

### Automatic optional facet filter

Same as `automaticFacetFilters`, but the filters are optional.
Behaves like [`optionalFilters`](/doc/api-reference/api-parameters/optionalFilters).

### Remove or replace a word from the query string

Removing or replacing words is achieved by specifying a list of **edits** to be applied to the query string.
An edit can either:

* Remove a word (or facet placeholder)
* Replace a word (or facet placeholder) with another word

For example, the following rule specifies that when matching `foo bar`,
Algolia should remove the word `foo` and the word `bar`
should be replaced with `baz`:

```json JSON icon=braces theme={"system"}
{
  "condition": [
    {
      "pattern": "foo bar"
    }
  ],
  "consequence": {
    "params": {
      "query": {
        "edits": [
          {
            "type": "remove",
            "delete": "foo"
          },
          {
            "type": "replace",
            "delete": "bar",
            "insert": "baz"
          }
        ]
      }
    }
  }
}
```

<Info>
  Words that are removed or replaced from the query string are still highlighted or showing in the snippets in the query's results,
  so it's not misleading for users.
</Info>

### Entirely replace the query string

To entirely replace the query string,
specify a new string for the `query` parameter, as you would do for any
other search parameters:

```json JSON icon=braces theme={"system"}
{
  "condition": [
    {
      "pattern": "original query that will be replaced"
    }
  ],
  "consequence": {
    "params": {
      "query": "new text to be searched"
    }
  }
}
```

<Info>
  You can't combine full query replacement with removing or replacing individual words in the same rule.
  But you can remove and replace individual words in the same rule.
  This can affect how later rules apply.
  For more information, see [Matching algorithm](/doc/guides/managing-results/rules/rules-overview/in-depth/rule-matching-algorithm).
</Info>

### Promote or hide specific hits

One or more objects from the same index, identified by their `objectID`, are promoted to specific positions in the results list or removed from them. This promotion works seamlessly with Algolia's built-in pagination, mingling promoted hits with regular
hits and removing hidden hits while keeping pages the same size.

For more information, see [Hit promotion's effect on relevance](#hit-promotions-effect-on-relevance).

### Return user data

User data is returned in a dedicated `userData` array.
If multiple rules are applied,
each set of user data is appended to this array.
User data can be used to display specific information that doesn't affect pagination.

For more information, see [Add banners to results With `userData`](/doc/guides/managing-results/rules/merchandising-and-promoting/how-to/add-banners).

## Hit promotion's effect on relevance

You can only promote objects coming from the same index.
Promoted objects have to be explicitly identified by their `objectID`.

A promoted object will always be considered a hit, even if it doesn't match the query.
If it would have matched the query, it's removed from its original position and inserted at its promoted position,
even if the original position would have been better than the promoted position.
In other words, promoted hits can also be "demoted".
For performance reasons,
promoted positions can be between 0 and 300.

Inside the same rule, each promoted object must have a different promoted position.
If promoted objects from two distinct rules are triggered for the same query:

* Any duplicates are merged using the best position.
* If the resulting positions conflict between distinct <Records />,
  records are shifted down until a free slot is found.
* All regular hits are shifted down until all promoted records get as close to their promoted position as possible (except conflicts between records, as stated before).

Hidden records are removed from the hits.
The following hits are shifted up so that pagination works seamlessly.

## Inject user data

User data lets you inject data inside the results that aren't in the index,
and as such, don't compete with other hits for pagination.
A typical use-case would be to display a banner on top of the result list.

User data can be any JSON object.
The API doesn't interpret user data.

If you want to keep your analytics data for longer,
[upgrade your plan](https://www.algolia.com/pricing) or contact the [Algolia support](https://support.algolia.com/hc/en-us/requests/new) team.
