Skip to content

Commit 732ee7b

Browse files
committed
docs: add search rules documentation
1 parent 04e9e1f commit 732ee7b

8 files changed

Lines changed: 618 additions & 1 deletion

File tree

capabilities/overview.mdx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
---
22
title: Capabilities overview
33
sidebarTitle: Overview
4-
description: Explore all Meilisearch capabilities, from full-text and semantic search to filtering, analytics, and multi-tenancy.
4+
description: Explore all Meilisearch capabilities, from full-text and semantic search to filtering, curation, analytics, and multi-tenancy.
55
---
66

77
Meilisearch provides a comprehensive set of search and data management capabilities. Each capability is documented with an overview, getting started guide, how-to guides, and advanced topics.
@@ -25,6 +25,9 @@ Meilisearch provides a comprehensive set of search and data management capabilit
2525
<Card title="Filtering, sorting, and faceting" icon="filter" href="/capabilities/filtering_sorting_faceting/overview">
2626
Narrow, order, and categorize results with filters, sort rules, and faceted navigation.
2727
</Card>
28+
<Card title="Search rules" icon="thumbtack" href="/capabilities/search_rules/overview">
29+
Curate search results by pinning selected documents when query- or time-based conditions match.
30+
</Card>
2831
<Card title="Personalization" icon="user" href="/capabilities/personalization/overview">
2932
Re-rank search results based on user context and behavior for tailored experiences.
3033
</Card>
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
---
2+
title: Search rule behavior
3+
sidebarTitle: Pinning behavior
4+
description: Learn how search rules interact with ranking, filters, precedence, and different search modes.
5+
---
6+
7+
Search rules are easiest to reason about as a curation layer that runs alongside normal search. This page covers the behavior that matters most when you build production workflows around them.
8+
9+
## Pinning does not change ranking
10+
11+
In the current implementation, pinning does not rewrite your ranking rules or assign artificial scores to pinned documents. Meilisearch still computes organic results first, then inserts the surviving pinned documents at their requested positions.
12+
13+
This behavior is specific to pinning. Other action types, such as boosting or burying, would affect ranking differently, but search rules do not support those actions today.
14+
15+
Organic ranking still decides the order of every non-pinned hit.
16+
17+
## Pinned documents do not need to match the query text
18+
19+
A pinned document can appear even if it is not a lexical match for the full query. As long as the rule matches, the document exists, and it survives filters, Meilisearch can insert it into the result list.
20+
21+
This is often what you want for help centers, promotions, and landing pages.
22+
23+
## Filters still apply
24+
25+
Pinned documents do not bypass filters. If the current search filters exclude a pinned document, Meilisearch drops it instead of forcing it into the response.
26+
27+
Use this behavior to keep search rules compatible with visibility restrictions, safety controls, and authenticated content.
28+
29+
## Matching behavior of `contains`
30+
31+
The query condition `contains` is a strict substring match. Describe it as a case-insensitive literal substring match, not as fuzzy, semantic, or pattern-aware matching.
32+
33+
For example, `contains: "call history"` matches `where is call history`, but it should not be described as matching `history of calls`.
34+
35+
Search rules do not currently support regex, wildcards, or numeric-pattern matching such as "any 6-digit code".
36+
37+
## Precedence between rules
38+
39+
Use `priority` to control which rule wins when several matching rules compete. Lower numeric values take precedence over higher ones.
40+
41+
If you omit `priority`, treat the rule as having the lowest precedence.
42+
43+
## Result-set behavior
44+
45+
Search rules preserve normal response behavior:
46+
47+
- A document should not appear twice if it is both organic and pinned
48+
- Pagination remains coherent
49+
- Facet distribution stays consistent with the final surviving result set
50+
- Search rules work in regular search, hybrid search, federated search, and network search
51+
52+
## Current scope
53+
54+
Search rules are currently instance-level rules. They are not stored as per-index settings.
55+
56+
Selectors can optionally include `indexUid` when you need to target a document in a specific index.
57+
58+
## Current limitations
59+
60+
Search rules do not currently support:
61+
62+
- Activation from request filters
63+
- Activation from selected facets
64+
- Activation from locale, user context, or page context
65+
- Actions other than pinning
66+
67+
This makes the current feature well suited to curated pinning, but not to full personalization or broader contextual merchandising.
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
---
2+
title: Getting started with search rules
3+
sidebarTitle: Getting started
4+
description: Enable search rules, create your first rule, and verify how pinned results appear in search.
5+
---
6+
7+
This guide walks you through enabling search rules, creating your first rule, and checking how it affects search results.
8+
9+
## Prerequisites
10+
11+
- A running Meilisearch instance
12+
- An admin API key
13+
- An index with documents. This guide uses a `support` index
14+
15+
## Step 1: Enable search rules
16+
17+
Search rules are experimental. Enable them with `PATCH /experimental-features`:
18+
19+
```json
20+
{
21+
"dynamicSearchRules": true
22+
}
23+
```
24+
25+
If the feature is disabled, the `/dynamic-search-rules` routes are not usable and saved rules do not apply at search time.
26+
27+
## Step 2: Create a rule
28+
29+
Create a rule with `PATCH /dynamic-search-rules/invoice-help`:
30+
31+
```json
32+
{
33+
"description": "Promote billing help for invoice searches",
34+
"active": true,
35+
"conditions": [
36+
{ "scope": "query", "contains": "invoice" }
37+
],
38+
"actions": [
39+
{
40+
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
41+
"action": { "type": "pin", "position": 0 }
42+
}
43+
]
44+
}
45+
```
46+
47+
This route behaves as an upsert:
48+
49+
- It returns `201 Created` when the rule does not exist yet
50+
- It returns `200 OK` when you update an existing rule
51+
52+
## Step 3: Check the stored rule
53+
54+
Retrieve the rule with `GET /dynamic-search-rules/invoice-help`.
55+
56+
The response should include the rule's `uid`, conditions, and actions:
57+
58+
```json
59+
{
60+
"uid": "invoice-help",
61+
"description": "Promote billing help for invoice searches",
62+
"active": true,
63+
"conditions": [
64+
{ "scope": "query", "contains": "invoice" }
65+
],
66+
"actions": [
67+
{
68+
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
69+
"action": { "type": "pin", "position": 0 }
70+
}
71+
]
72+
}
73+
```
74+
75+
## Step 4: Run a matching search
76+
77+
Send a normal search request to your index, for example with `POST /indexes/support/search`:
78+
79+
```json
80+
{
81+
"q": "invoice settings"
82+
}
83+
```
84+
85+
If `billing-workspace-overview` exists and survives the current filters, Meilisearch inserts it at position `0`.
86+
87+
Search rules do not replace the rest of the result set. Meilisearch still computes the normal organic results, then inserts the pinned documents and removes duplicates.
88+
89+
## Next steps
90+
91+
<CardGroup cols={2}>
92+
<Card title="How to" href="/capabilities/search_rules/how_to/pinning_patterns">
93+
Explore common query, empty-query, and time-window patterns
94+
</Card>
95+
<Card title="Reference" href="/capabilities/search_rules/reference">
96+
Review endpoints, rule fields, and update behavior
97+
</Card>
98+
<Card title="Advanced" href="/capabilities/search_rules/advanced/pinning_behavior">
99+
Learn how search rules interact with ranking and filters
100+
</Card>
101+
<Card title="Experimental features" href="/resources/help/experimental_features_overview">
102+
Learn more about experimental feature management
103+
</Card>
104+
</CardGroup>
Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
---
2+
title: Search rule patterns
3+
sidebarTitle: Pinning patterns
4+
description: Task-oriented guides for common search rule patterns such as query-based pinning, empty-query curation, and scheduled promotions.
5+
---
6+
7+
All create and update examples on this page use `PATCH /dynamic-search-rules/{uid}`. The `uid` comes from the path, and omitted fields remain unchanged when you update an existing rule.
8+
9+
## How do I pin one result for a query?
10+
11+
Pin a document whenever the query contains a specific substring:
12+
13+
```json
14+
{
15+
"description": "Promote billing help for invoice searches",
16+
"active": true,
17+
"conditions": [
18+
{ "scope": "query", "contains": "invoice" }
19+
],
20+
"actions": [
21+
{
22+
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
23+
"action": { "type": "pin", "position": 0 }
24+
}
25+
]
26+
}
27+
```
28+
29+
Use this pattern when you want to promote a landing page, help article, or campaign document for a specific query family.
30+
31+
## How do I pin several results in a fixed order?
32+
33+
Add multiple actions with explicit positions:
34+
35+
```json
36+
{
37+
"description": "Show billing resources first for invoice searches",
38+
"active": true,
39+
"conditions": [
40+
{ "scope": "query", "contains": "invoice" }
41+
],
42+
"actions": [
43+
{
44+
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
45+
"action": { "type": "pin", "position": 0 }
46+
},
47+
{
48+
"selector": { "indexUid": "support", "id": "download-monthly-statements" },
49+
"action": { "type": "pin", "position": 1 }
50+
}
51+
]
52+
}
53+
```
54+
55+
This keeps the pinned documents in a predictable order while leaving the rest of the hits in their normal organic order.
56+
57+
## How do I curate the default results for an empty query?
58+
59+
Use the `isEmpty` query condition to curate the browse state when users search with an empty query:
60+
61+
```json
62+
{
63+
"description": "Curate the default help-center browse state",
64+
"active": true,
65+
"conditions": [
66+
{ "scope": "query", "isEmpty": true }
67+
],
68+
"actions": [
69+
{
70+
"selector": { "indexUid": "support", "id": "quickstart-overview" },
71+
"action": { "type": "pin", "position": 0 }
72+
}
73+
]
74+
}
75+
```
76+
77+
This is useful when users often start by browsing instead of typing a search.
78+
79+
## How do I schedule a promotion for a limited time?
80+
81+
Combine a query condition with a time condition:
82+
83+
```json
84+
{
85+
"description": "Promote seasonal content during a campaign window",
86+
"active": true,
87+
"conditions": [
88+
{ "scope": "query", "contains": "summer sale" },
89+
{ "scope": "time", "start": "2026-06-01T00:00:00Z", "end": "2026-06-30T23:59:59Z" }
90+
],
91+
"actions": [
92+
{
93+
"selector": { "indexUid": "products", "id": "summer-sale-landing-page" },
94+
"action": { "type": "pin", "position": 0 }
95+
}
96+
]
97+
}
98+
```
99+
100+
Multiple conditions are combined with `AND`, so this rule only applies during the campaign window and only when the query contains `summer sale`.
101+
102+
## How do I list active rules or rules with similar UIDs?
103+
104+
Use `POST /dynamic-search-rules` with pagination and filters:
105+
106+
```json
107+
{
108+
"offset": 0,
109+
"limit": 20,
110+
"filter": {
111+
"attributePatterns": ["promo*"],
112+
"active": true
113+
}
114+
}
115+
```
116+
117+
`attributePatterns` uses attribute-pattern syntax, for example `promo*`.
118+
119+
## How do I pause a rule without deleting it?
120+
121+
Set `active` to `false`:
122+
123+
```json
124+
{
125+
"active": false
126+
}
127+
```
128+
129+
Use `DELETE /dynamic-search-rules/{uid}` only when you want to remove the rule entirely.

0 commit comments

Comments
 (0)