Implementing Rules
On this page
Using the Rules dashboard
We suggest that you use the dashboard to familiarize yourself with Rules. The dashboard provides a responsive interface to create and configure your Rules. And importantly, you can easily test your choices live using the Dashboard’s search interface.
In fact, you might never need to go beyond the dashboard - especially if your Rules are few or they follow a very clearly 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.
For the dashboard, you’ll need to go to the Rules tab for a selected index and click on Add Rule. Here you can choose between two editors:
- The Visual Editor allows you to pin results and hide results, boost categories, and filter results through a really simple, visual and guided user journey.
- The Manual Editor supports more options, but doesn’t offer an instant preview of the results.
Coding Rules with the API Client
Coding the Rules using the Rules API becomes necessary when you need more programmatic control. This move from static to more dynamic Rules can arise for a number of reasons - like when the Rules become too numerous to manage one-by-one, or when you want to start building (and deleting) Rules based on the content of your database. You’ll need to use the API if your Rules change with every new update of your index, or if you provide your own frontend to manage your Rules.
For the API, you’ll need to set up your index properly, and then set up the Rules at indexing time.
How Rules works
Rules are essentially if-then configurations, or condition/consequence pairs: if the condition is satisfied, the consequence applies to the returned results.
Broadly speaking, the search engine adapts its behavior according to the Rule’s consequences.
For example, a Rule could have 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 our overview, and presented in technical detail below - there are many kinds of consequences that adapt the search and alter the relevance.
Rules are processed at indexing time. This prepares 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 isn’t set totrue
, then the condition needs to match the entire word (fully and exactly) 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.
Rules comes with no noticeable impact on performance. Most of the work happens during indexing, so they don’t affect search performance.
Enabling & disabling Rules
You may disable a Rule by setting its enabled
flag to false
. Disabled Rules remain in the index, meaning they are still searchable, but are ignored at query time. This is a handy alternative to deleting a Rule when you wish to
disable it only temporarily.
For even more fine-grained control, you may specify validity windows on Rules (via the validity
attribute). Rules with validity windows only apply during the specified time frames; they are 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 / Post-processing
As suggested, Rules allows fine-tuning results for queries matching specific patterns. They do so in two complementary ways:
-
Query pre-processing. Rules may alter the query parameters - not only the query string, but also filters, facets, etc. - before the query is processed.
-
Results post-processing. Rules may cause results (hits) to be ranked differently for specific queries. They may 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.
Condition / Consequence
The general syntax is as follows:
1
2
3
4
{
"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
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 is composed of:
- An optional query pattern (acting on the full text query string, i.e., the
query
search parameter). - An optional anchoring defining how the Rule’s query pattern is compared to user queries.
- An optional filter or filters, which must match the filters applied with the query. These could be
filters
orfacetFilters
, but notnumericFilters
,tagFilters
, noroptionalFilters
. - An optional context, which must match a context supplied at query time (via the
ruleContexts
parameter). - Optionally enabled alternatives, which indicates whether synonyms and plurals of the query pattern should be treated as matches.
Consequence
A Rule’s consequence can be one or more actions.
- Add query parameters
- Automatic facet filter
- Automatic optional facet filter
- Remove or replace a word from the query string
- Replace the query string entirely
- Promote or hide specific hits
- Return user data.
Conditions - adapting the query
A Rule can have any number of conditions. If a Rule has no conditions, it applies to every search. If it has more than one condition, all conditions must be met for the Rule to apply.
Query pattern
The query pattern is the most important piece of the Rule’s condition. It consists of a sequence of tokens, treated as a phrase (i.e. 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 the
alternatives
setting of a Rule’s condition is set totrue
, then matching takes into account typo tolerance, plurals and synonyms. Note that if you setignorePlurals
totrue
orsynonyms
tofalse
, youralternatives
setting is ignored. - Facet value placeholder: matches any value of a given facet in the same index.
The facet must have been declared in attributesForFaceting
.
Matching is case insensitive. Contrary to literals, facet values may be phrases.
It is worth noting that the pattern is implicitly a phrase,
i.e. the order of words matters: foo bar
and bar foo
are not identical patterns.
In addition, the pattern has an anchoring type, depending on whether its boundaries (beginning, end) must coincide with the boundaries of the query string:
- is: the pattern matches the entire query string;
- starts with: the pattern must match the beginning of the query string, but there may be extra words at the end;
- ends with: the pattern must match the end of the query string, but there may be extra words at the beginning;
- contains: the pattern can match any part of the query string.
Escape characters within a pattern
If you want to declare a Rule with a pattern that contains a colon (:
), or any special character (}
, {
, \
), you need to escape the character.
For example, to set your query pattern to “thrones: episode”, you need to escape the :
(“thrones\:episode”). The first \
is for JSON and the second is for the Rules engine.
Filters
Rules can be triggered by filters
or facetFilters
. 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, the engine applies the Rule’s consequences to any search where the given filter or filters are included. If a condition also has a query pattern and/or a context, then those must match too for the Rule to be triggered.
To use an attribute in a Rule condition with filters, you must first declare it in attributesForFaceting
.
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 precedence logic applied on 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 only 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
. The engine 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 exactly to trigger the Rule. For example, if the Rule condition is "filters":"brand:Nike AND color:red"
, then the engine triggers this Rule if only the value Nike
is selected in thebrand
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, the engine only considers the brand
attribute’s applied filter values to determine whether to trigger the Rule.
For example, if a query is filtered 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. The engine 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 the engine interprets a condition containing brand:Supreme
, brand:Nike
, gender:men
as (brand:Supreme OR brand:Nike) AND (gender:men)
.
In other words, the engine triggers the Rule if a user selects the values (Supreme
and men
), or (Nike
and men
), or (Supreme
, Nike
and men
) in the filters on the front end.
This is only true if the front-end filters work with the same ANDs of ORs
logic. For example, if as 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, imagine a real estate search where a user filters for a 2 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 amenties: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 search 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. By activation, we mean that the Rule is considered not 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, then that pattern must be matched 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.
This results in a set of Rules that apply to the homepage search, giving a more customized search 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.
Note that 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 exact same value for the Rule to be triggered. Matching is case sensitive.
The ruleContexts
parameter is an array of contexts, which allows you to enable multiple contexts at the same time
A Rule context must consist only of alphanumeric characters, hyphens, and underscores.
Consequence - adapting the results / relevance
A Rule’s consequence can be one or more actions.
Add query parameters
Any number of any valid search parameters are supported. Note that these parameters are literals, i.e. constants.
What this consequence allows you to do is add or change any of the search settings that have the option to be changed at query time (the time when the query is sent to Algolia). Note that some settings that affect search can only be set at indexing time, meaning they cannot be changed “on the fly” at query time, like Searchable Attributes.
Within the list of all our search parameters, anytime the parameter has search
as part of its scope, it can be changed on the fly at query time.
One common example of a search parameter that is useful to change at query time is the filters
parameter. Let’s say when someone searches “tablet”, you want to show not only tablets (e.g. products with ‘tablets’ in their categories
attribute) but also laptops that can be used as tablets (e.g. products with ‘hybrids’ in their categories
attribute). To do this in the dashboard, click Add Query Parameter when adding a consequence for your Query Rule, and add the following JSON into the editor:
1
2
3
{
"filters": "categories:tablets OR categories:hybrids"
}
You can also add filters with 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. User enters “red”, which is also a value in the color facet. A Rule can be set up 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 will need to have 1 Rule per filter value. So if you have 10 color values in your color facet, you will need to create 10 Rules, 1 for each color.
It is more powerful to use automatic faceting: instead of creating 1 Rule for each color, you create 1 Rule per facet. Whether the user types “blue” or “red”, this single Rule will apply. It also applies to new colors added to the facet.
Filters can be either conjunctive (AND
, default) or disjunctive (OR
). This only applies when the pattern
matches multiple values of the same facet. In that situation, the Rule matches multiple times, hence producing
multiple filters. By default, the produced filters are combined with an AND
operator. If you specify the filter to be
disjunctive, however, an OR
operator is used instead. Note that, in both cases, relationships to other filters
in the query will always be conjunctive (AND
).
Optionally, a score can be specified for the created filter. This is useful mainly for optional facet filters (see below).
For example, to automatically filter on the brand
facet, using OR
in case of multiple occurrences:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
/* [...] */
"conditions": [
{
"pattern": "{facet:brand}"
/* [...] */
}
],
"consequence": {
"params": {
"automaticFacetFilters": [
{
"facet": "brand",
"disjunctive": "true"
}
]
}
}
}
Automatic optional facet filter
Same as automaticFacetFilters
, but the filters are optional.
Behaves like optionalFacetFilters
.
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 Rule below specifies that when matching foo bar
, the word foo
should be removed and the word bar
should be replaced with baz
:
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
{
/* [...] */
"condition": [
{
"pattern": "foo bar"
/* [...] */
}
],
"consequence": {
"params": {
"query": {
"edits": [
{
"type": "remove",
"delete": "foo"
},
{
"type": "replace",
"delete": "bar",
"insert": "baz"
}
]
}
}
}
}
Words that are removed or replaced from the query string are still highlighted or snippeted in the query’s results, so it’s not misleading for the end user.
Replace the query string entirely
To replace the query string entirely, specify a new string for the query
parameter, as you would do for any
other search parameter:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
{
/* [...] */
"condition": [
{
"pattern": "original query that will be replaced"
/* [...] */
}
],
"consequence": {
"params": {
"query": "new text to be searched"
}
}
}
This and removing a word are mutually exclusive Rules. It may also have an impact on subsequent Rules (see Matching algorithm).
Promote or hide specific hits
One or more objects from the same index, identified by their objectID
, are promoted to specific positions in the hits,
or removed from them. This works seamlessly with Algolia’s built-in pagination, mingling promoted hits with regular
hits and removing hidden hits while keeping pages the same size.
Hit promotion is detailed below.
Return user data.
This user data is returned outside of the hits, in a dedicated userData
array. If multiple Rules are applied,
each user data is appended to this array. User data can be used to display specific information that does not affect pagination.
Some final considerations
Hit promotion’s effect on relevance
Only objects coming from the same index can be promoted. 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 is 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 are restricted to the range [0, 300] (keep in mind that positions are zero-based).
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 objects, objects are shifted down until a free slot is found.
- All regular hits are shifted down as many times as necessary to ensure that all promoted objects get as close to their promoted position as possible (modulo conflicts between objects, as stated above).
Hidden objects are removed from the hits. The following hits are shifted up so that pagination works seamlessly.
Injecting user data
User data allows to inject data inside the results that are not objects coming from the index, and as such doesn’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. It is not interpreted by the API whatsoever.