Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion capabilities/overview.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Capabilities overview
sidebarTitle: Overview
description: Explore all Meilisearch capabilities, from full-text and semantic search to filtering, analytics, and multi-tenancy.
description: Explore all Meilisearch capabilities, from full-text and semantic search to filtering, curation, analytics, and multi-tenancy.
---

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.
Expand All @@ -25,6 +25,9 @@ Meilisearch provides a comprehensive set of search and data management capabilit
<Card title="Filtering, sorting, and faceting" icon="filter" href="/capabilities/filtering_sorting_faceting/overview">
Narrow, order, and categorize results with filters, sort rules, and faceted navigation.
</Card>
<Card title="Search rules" icon="thumbtack" href="/capabilities/search_rules/overview">
Curate search results by pinning selected documents when query- or time-based conditions match.
</Card>
<Card title="Personalization" icon="user" href="/capabilities/personalization/overview">
Re-rank search results based on user context and behavior for tailored experiences.
</Card>
Expand Down
67 changes: 67 additions & 0 deletions capabilities/search_rules/advanced/pinning_behavior.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
title: Search rule behavior
sidebarTitle: Pinning behavior
description: Learn how search rules interact with ranking, filters, precedence, and different search modes.
---

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.

## Pinning does not change ranking

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.

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.

Organic ranking still decides the order of every non-pinned hit.

## Pinned documents do not need to match the query text

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.

This is often what you want for help centers, promotions, and landing pages.

## Filters still apply

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.

Use this behavior to keep search rules compatible with visibility restrictions, safety controls, and authenticated content.

## Matching behavior of `contains`

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.

For example, `contains: "call history"` matches `where is call history`, but it should not be described as matching `history of calls`.

Search rules do not currently support regex, wildcards, or numeric-pattern matching such as "any 6-digit code".

## Precedence between rules

Use `priority` to control which rule wins when several matching rules compete. Lower numeric values take precedence over higher ones.

If you omit `priority`, treat the rule as having the lowest precedence.

## Result-set behavior

Search rules preserve normal response behavior:

- A document should not appear twice if it is both organic and pinned
- Pagination remains coherent
- Facet distribution stays consistent with the final surviving result set
- Search rules work in regular search, hybrid search, federated search, and network search

## Current scope

Search rules are currently instance-level rules. They are not stored as per-index settings.

Selectors can optionally include `indexUid` when you need to target a document in a specific index.

## Current limitations

Search rules do not currently support:

- Activation from request filters
- Activation from selected facets
- Activation from locale, user context, or page context
- Actions other than pinning

This makes the current feature well suited to curated pinning, but not to full personalization or broader contextual merchandising.
104 changes: 104 additions & 0 deletions capabilities/search_rules/getting_started.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
---
title: Getting started with search rules
sidebarTitle: Getting started
description: Enable search rules, create your first rule, and verify how pinned results appear in search.
---

This guide walks you through enabling search rules, creating your first rule, and checking how it affects search results.

## Prerequisites

- A running Meilisearch instance
- An admin API key
- An index with documents. This guide uses a `support` index

## Step 1: Enable search rules

Search rules are experimental. Enable them with `PATCH /experimental-features`:

```json
{
"dynamicSearchRules": true
}
```

If the feature is disabled, the `/dynamic-search-rules` routes are not usable and saved rules do not apply at search time.

## Step 2: Create a rule

Create a rule with `PATCH /dynamic-search-rules/invoice-help`:

```json
{
"description": "Promote billing help for invoice searches",
"active": true,
"conditions": [
{ "scope": "query", "contains": "invoice" }
],
"actions": [
{
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
"action": { "type": "pin", "position": 0 }
}
]
}
```

This route behaves as an upsert:

- It returns `201 Created` when the rule does not exist yet
- It returns `200 OK` when you update an existing rule

## Step 3: Check the stored rule

Retrieve the rule with `GET /dynamic-search-rules/invoice-help`.

The response should include the rule's `uid`, conditions, and actions:

```json
{
"uid": "invoice-help",
"description": "Promote billing help for invoice searches",
"active": true,
"conditions": [
{ "scope": "query", "contains": "invoice" }
],
"actions": [
{
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
"action": { "type": "pin", "position": 0 }
}
]
}
```

## Step 4: Run a matching search

Send a normal search request to your index, for example with `POST /indexes/support/search`:

```json
{
"q": "invoice settings"
}
```

If `billing-workspace-overview` exists and survives the current filters, Meilisearch inserts it at position `0`.

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.

## Next steps

<CardGroup cols={2}>
<Card title="How to" href="/capabilities/search_rules/how_to/pinning_patterns">
Explore common query, empty-query, and time-window patterns
</Card>
<Card title="Reference" href="/capabilities/search_rules/reference">
Review endpoints, rule fields, and update behavior
</Card>
<Card title="Advanced" href="/capabilities/search_rules/advanced/pinning_behavior">
Learn how search rules interact with ranking and filters
</Card>
<Card title="Experimental features" href="/resources/help/experimental_features_overview">
Learn more about experimental feature management
</Card>
</CardGroup>
129 changes: 129 additions & 0 deletions capabilities/search_rules/how_to/pinning_patterns.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
---
title: Search rule patterns
sidebarTitle: Pinning patterns
description: Task-oriented guides for common search rule patterns such as query-based pinning, empty-query curation, and scheduled promotions.
---

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.

## How do I pin one result for a query?

Pin a document whenever the query contains a specific substring:

```json
{
"description": "Promote billing help for invoice searches",
"active": true,
"conditions": [
{ "scope": "query", "contains": "invoice" }
],
"actions": [
{
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
"action": { "type": "pin", "position": 0 }
}
]
}
```

Use this pattern when you want to promote a landing page, help article, or campaign document for a specific query family.

## How do I pin several results in a fixed order?

Add multiple actions with explicit positions:

```json
{
"description": "Show billing resources first for invoice searches",
"active": true,
"conditions": [
{ "scope": "query", "contains": "invoice" }
],
"actions": [
{
"selector": { "indexUid": "support", "id": "billing-workspace-overview" },
"action": { "type": "pin", "position": 0 }
},
{
"selector": { "indexUid": "support", "id": "download-monthly-statements" },
"action": { "type": "pin", "position": 1 }
}
]
}
```

This keeps the pinned documents in a predictable order while leaving the rest of the hits in their normal organic order.

## How do I curate the default results for an empty query?

Use the `isEmpty` query condition to curate the browse state when users search with an empty query:

```json
{
"description": "Curate the default help-center browse state",
"active": true,
"conditions": [
{ "scope": "query", "isEmpty": true }
],
"actions": [
{
"selector": { "indexUid": "support", "id": "quickstart-overview" },
"action": { "type": "pin", "position": 0 }
}
]
}
```

This is useful when users often start by browsing instead of typing a search.

## How do I schedule a promotion for a limited time?

Combine a query condition with a time condition:

```json
{
"description": "Promote seasonal content during a campaign window",
"active": true,
"conditions": [
{ "scope": "query", "contains": "summer sale" },
{ "scope": "time", "start": "2026-06-01T00:00:00Z", "end": "2026-06-30T23:59:59Z" }
],
"actions": [
{
"selector": { "indexUid": "products", "id": "summer-sale-landing-page" },
"action": { "type": "pin", "position": 0 }
}
]
}
```

Multiple conditions are combined with `AND`, so this rule only applies during the campaign window and only when the query contains `summer sale`.

## How do I list active rules or rules with similar UIDs?

Use `POST /dynamic-search-rules` with pagination and filters:

```json
{
"offset": 0,
"limit": 20,
"filter": {
"attributePatterns": ["promo*"],
"active": true
}
}
```

`attributePatterns` uses attribute-pattern syntax, for example `promo*`.

## How do I pause a rule without deleting it?

Set `active` to `false`:

```json
{
"active": false
}
```

Use `DELETE /dynamic-search-rules/{uid}` only when you want to remove the rule entirely.
Loading
Loading