From 67ccdb78019d34a6bb588f76f88365c9c9297318 Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 10:24:26 +0000 Subject: [PATCH 01/11] 2 new guides and new section --- docs.json | 7 + .../relevancy/interpreting_ranking_scores.mdx | 308 ++++++++++++++++++ guides/relevancy/ordering_ranking_rules.mdx | 122 +++++++ 3 files changed, 437 insertions(+) create mode 100644 guides/relevancy/interpreting_ranking_scores.mdx create mode 100644 guides/relevancy/ordering_ranking_rules.mdx diff --git a/docs.json b/docs.json index 2b6d27598..e16cb3d13 100644 --- a/docs.json +++ b/docs.json @@ -433,6 +433,13 @@ "guides/multitenancy_nodejs" ] }, + { + "group": "Relevancy", + "pages": [ + "guides/relevancy/ordering_ranking_rules", + "guides/relevancy/interpreting_ranking_scores" + ] + }, { "group": "Deployment", "pages": [ diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx new file mode 100644 index 000000000..db7466fdc --- /dev/null +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -0,0 +1,308 @@ +--- +title: Interpreting ranking score details +description: Learn how to understand ranking score details to see how Meilisearch evaluates each result and which rules determined their order. +--- + +# How Do I Interpret Ranking Score Details? + +[In the previous guide](/guides/relevancy/ordering_ranking_rules), we covered how ranking rules determine result order and how changing their sequence affects what your users see first. But when you're actually making those tweaks, how do you know if they're working the way you expect? + +That's where ranking score details come in. They give you a behind-the-scenes view of every ranking decision Meilisearch made for each result — with specific numeric scores for each relevancy rule, in the order they were evaluated. + +You'll be able to see things like: did Proximity decide this result's position, or was it Typo? Did Sort even get a chance to act, or did an earlier rule already settle things? And since Sort doesn't measure relevance (it shows a `value` rather than a `score`), the details also make it clear exactly where Sort slotted into the evaluation path and whether it actually influenced the final order. + +**Firstly, how do I see ranking score details?** + +When you search you can pass in an option to view the details of scoring and sorting using `“showRankingScoreDetails”: true` and it will return an indepth look at the ranking rules that you are working with + +```markdown +curl \ + -X POST 'MEILISEARCH_URL/indexes/movies/search' \ + -H 'Content-Type: application/json' \ + --data-binary '{ + "q": "dragon", + "showRankingScoreDetails": true + }' +``` + +Ranking Score details example + +```markdown +{ + "hits": [ + { + "id": 31072, + "title": "Dragon", + "overview": "In a desperate attempt to save her kingdom…", + … + **"_rankingScoreDetails"**: { + "words": { + "order": 0, + "matchingWords": 4, + "maxMatchingWords": 4, + "score": 1.0 + }, + "typo": { + "order": 2, + "typoCount": 1, + "maxTypoCount": 4, + "score": 0.75 + }, + "name:asc": { + "order": 1, + "value": "Dragon" + } + } + }, + … + ], + … +} +``` + +# Ranking rules: Same Data, Different Results. How Sort Placement Changes Outcomes + +## The Setup + +You run a **recipe search app**. You have two recipes in your index: + +```json +[ + { + "id": 1, + "title": "Easy Chicken Curry", + "description": "A quick and simple chicken curry ready in 20 minutes", + "prep_time_minutes": 20 + }, + { + "id": 2, + "title": "Chicken Stew with Curry Spices and Vegetables", + "description": "A hearty stew with warming spices", + "prep_time_minutes": 15 + } +] +``` + +A user searches for `"chicken curry"` and sorts by `prep_time_minutes:asc` (quickest first). + +Both documents match both search words. But **Doc 1** is clearly the stronger text match as `"chicken"` and `"curry"` appear right next to each other in the title. **Doc 2** has both words in the title too, but they're separated by several other words. + +Let's see how moving Sort **one position** in your ranking rules changes which result comes first, and how to read the ranking score details to understand why. + +--- + +## Scenario A: Sort placed AFTER Group 1 rules (recommended) + +We’ve set up our ranking rules to have sort after our Group 1 wide net rules. + +```json +["words", "typo", "proximity", "sort", "attribute", "exactness"] +``` + +With this set up Meilisearch evaluates the text relevance rules first, *then* uses Sort. + +### 🥇 Result #1 — Easy Chicken Curry + +```json +{ + "prep_time_minutes": 20, + "title": "Easy Chicken Curry", + "id": 1, + "description": "A quick and simple chicken curry ready in 20 minutes", + "_rankingScore": 0.9982363315696648, + "_rankingScoreDetails": { + "words": { + "order": 0, + "matchingWords": 2, + "maxMatchingWords": 2, + **"score": 1.0** + }, + "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, "**score": 1.0** }, + "proximity": { "order": 2, "**score": 1.0** }, + "prep_time_minutes:asc": { "order": 3, "value": 20.0 }, + "attribute": { + "order": 4, + "attributeRankingOrderScore": 1.0, + "queryWordDistanceScore": 0.9047619047619048, + "score": 0.9682539682539683 + }, + "exactness": { + "order": 5, + "matchType": "noExactMatch", + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 0.3333333333333333 + } + } + } +``` + +### 🥈 Result #2 — Chicken Stew with Curry Spices and Vegetables + +```json +{ + "prep_time_minutes": 15, + "title": "Chicken Stew with Curry Spices and Vegetables", + "id": 2, + "description": "A hearty stew with warming spices", + "_rankingScore": 0.9149029982363316, + "_rankingScoreDetails": { + "words": { + "order": 0, + "matchingWords": 2, + "maxMatchingWords": 2, + **"score": 1.0** + }, + "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, **"score": 1.0** }, + "proximity": { "order": 2, **"score": 0.5** }, + "prep_time_minutes:asc": { "order": 3, "value": 15.0 }, + "attribute": { + "order": 4, + "attributeRankingOrderScore": 1.0, + "queryWordDistanceScore": 0.9047619047619048, + "score": 0.9682539682539683 + }, + "exactness": { + "order": 5, + "matchType": "noExactMatch", + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 0.3333333333333333 + } + } + +``` + +### What decided this? Reading the score details + +Walk through the rules in `order` (0, 1, 2…) and look for where the scores diverge: + +| Step | Rule | Doc 1 | Doc 2 | Outcome | +| --- | --- | --- | --- | --- | +| 0 | **Words** | 2/2 → `1.0` | 2/2 → `1.0` | 🤝 Tie | +| 1 | **Typo** | 0 typos → `1.0` | 0 typos → `1.0` | 🤝 Tie | +| 2 | **Proximity** | `1.0` | `0.5` | ✅ **Doc 1 wins here** | + +Proximity broke the tie. `"chicken"` and `"curry"` sit right next to each other in Doc 1's title (score `1.0`), but are separated by three words in Doc 2's title (score `0.5`). + +Sort (order 3) never got a chance to act because Proximity already decided the winner. **Even though Doc 2 has a faster prep time (15 min vs 20 min), it ranks second because text relevance was evaluated first.** + +Also notice: Sort shows a `value` instead of a `score`. That's because Sort doesn't measure relevance, it just orders by the field value. This is why Sort doesn't contribute to `_rankingScore`. + +--- + +## Scenario B: Sort placed BEFORE Group 1 rules + +Now let's move `sort` to the top of our ranking rules: + +```json +["sort", "words", "typo", "proximity", "attribute", "exactness"] +``` + +### 🥇 Result #1 — Chicken Stew with Curry Spices and Vegetables + +```json + { + "prep_time_minutes": 15, + "title": "Chicken Stew with Curry Spices and Vegetables", + "id": 2, + "description": "A hearty stew with warming spices", + "_rankingScore": 0.9149029982363316, + "_rankingScoreDetails": { + **"prep_time_minutes:asc": { "order": 0, "value": 15.0 },** + "words": { + "order": 1, + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 1.0 + }, + "typo": { "order": 2, "typoCount": 0, "maxTypoCount": 2, "score": 1.0 }, + "proximity": { "order": 3, "score": 0.5 }, + "attribute": { + "order": 4, + "attributeRankingOrderScore": 1.0, + "queryWordDistanceScore": 0.9047619047619048, + "score": 0.9682539682539683 + }, + "exactness": { + "order": 5, + "matchType": "noExactMatch", + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 0.3333333333333333 + } + } + } +``` + +### 🥈 Result #2 — Easy Chicken Curry + +```json +{ + "prep_time_minutes": 20, + "title": "Easy Chicken Curry", + "id": 1, + "description": "A quick and simple chicken curry ready in 20 minutes", + "_rankingScore": 0.9982363315696648, + "_rankingScoreDetails": { + **"prep_time_minutes:asc": { "order": 0, "value": 20.0 },** + "words": { + "order": 1, + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 1.0 + }, + "typo": { "order": 2, "typoCount": 0, "maxTypoCount": 2, "score": 1.0 }, + "proximity": { "order": 3, "score": 1.0 }, + "attribute": { + "order": 4, + "attributeRankingOrderScore": 1.0, + "queryWordDistanceScore": 0.9047619047619048, + "score": 0.9682539682539683 + }, + "exactness": { + "order": 5, + "matchType": "noExactMatch", + "matchingWords": 2, + "maxMatchingWords": 2, + "score": 0.3333333333333333 + } + } + } +``` + +### Reading the score details - what changed? + +Look at the `order` values. Sort is now `order: 0` so it runs first. + +| Step | Rule | Doc 1 (Easy Chicken Curry) | Doc 2 (Chicken Stew…) | Outcome | +| --- | --- | --- | --- | --- | +| 0 | **Sort** (`prep_time_minutes:asc`) | value: `20` | value: `15` | ✅ **Doc 2 wins here** | + +Sort immediately separated the documents: 15 min beats 20 min. `:asc` will sort lowest to highest. Words, Typo, Proximity, and the rest never got a say. + +Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs 0.914)** but it ranks second. This is exactly what the guide means when it says ranking score only measures text relevance. Sort affects the final order but doesn't change the score. If you only looked at `_rankingScore`, you'd think Doc 1 should be first. The score details tell you the real story. + +--- + +## Side by Side + +| | Scenario A (Sort placed after Group 1 ranking rules) | Scenario B (Sort placed first) | +| --- | --- | --- | +| **#1 result** | Easy Chicken Curry (20 min) | Chicken Stew with Curry… (15 min) | +| **Decided by** | Proximity (order 2) | Sort (order 0) | +| **Doc 1 `_rankingScore`** | 0.998 | 0.998 (same — sort doesn't affect it) | +| **Doc 2 `_rankingScore`** | 0.914 | 0.914(same — sort doesn't affect it) | +| **Best for** | Users who want the most relevant recipe | Users who want the quickest recipe regardless of match quality | + +--- + +## The Takeaway + +Moving Sort **one position** flipped the results. The ranking score details let you see exactly why: + +- **Look at the `order` values** to understand the sequence rules were applied +- **Find where scores first diverge** — that's the rule that decided the final order +- **Remember that Sort shows a `value`, not a `score`** It doesn't contribute to `_rankingScore`, which is why a higher-scored document can rank lower when Sort takes priority + +Start with Sort after Group 1 rules (Scenario A) and adjust from there based on what your users expect. \ No newline at end of file diff --git a/guides/relevancy/ordering_ranking_rules.mdx b/guides/relevancy/ordering_ranking_rules.mdx new file mode 100644 index 000000000..1c1cf57d5 --- /dev/null +++ b/guides/relevancy/ordering_ranking_rules.mdx @@ -0,0 +1,122 @@ +--- +title: Ordering ranking rules +description: Learn how Meilisearch orders search results and how to customize ranking rule order for your use case. +--- + +# Ranking Rules: Getting the Order Right For You + +**When to Read This Guide** + +This guide is for you if you want to understand how Meilisearch orders your search results and how to customize that behavior for your specific use case. + +You might be here because you've noticed a document with a lower ranking score appearing above one with a higher score, or you're curious about what happens when you adjust the ranking rule sequence. Maybe you're proactively exploring how to fine-tune results before going live, or you want to prioritize certain types of content over others. + +**What you'll learn:** This guide explains how Meilisearch's ranking rules system works behind the scenes - how ranking scores relate to final result order, and how to adjust rankings to match your needs. You'll get practical tips and recommendations for common scenarios, so you can confidently tune your search results. + +## **How Meilisearch Ranks Results** + +### **Ranking Score vs. Final Order** + +**Ranking score only measures text match quality.** It doesn't include Sort or Custom ranking rules. + +Ever noticed a document with a lower ranking score appearing higher in results? That's normal. The ranking score captures text relevance, but your final result order also includes Sort and Custom ranking rules, which don’t care for textual relevancy, and so these don't contribute to the ranking score. Understanding how these two work together is important to tweak effectively. + +### **How Ranking Rules Work** + +Meilisearch applies ranking rules sequentially. Each rule sorts documents into buckets and passes them to the next rule. This is why rule order matters - earlier rules take priority and later rules serve only as tie-breakers. + +### Types of Ranking Rules + +**Group 1 - Broad matching: Word, Type, Proximity (included in ranking score)** + +This covers things like: + +- **Word**: How many of your search terms appear in the document (more matches = higher ranking) +- **Typo**: Whether these matches are the exact words or matches that are included through typo-tolerance (exact matches rank higher) +- **Proximity**: How close together your search terms appear in the document (closer = more relevant) + +**These three rules cast a wide net and return lots of results.** That's good—you want to start broad and then narrow down, not the other way around. If you start too narrow you can lose relevancy easily. + +**Group 2 - Fine-tuning : Exactness, Attribute (included in ranking score)** + +This covers things like: + +- **Exactness**: Did the document match your whole search term or just pieces of it? Whole matches rank higher, especially when an entire field matches exactly or starts with your query. Documents containing extra content beyond the search term are ranked lower. +- **Attribute**: Matches in your most important fields rank higher, and matches near the beginning of a field rank higher. You set field priority in `searchableAttributes`, with fields at the top of the list treated as the most important. + +**These are your fine-tuning filters.** They return fewer, more precise results. Use these after Group 1 rules to refine your large result set into something more precise. + +If you want to dive deeper into the [built in ranking rules](https://www.meilisearch.com/docs/learn/relevancy/ranking_rules) and [custom ranking rules](https://www.meilisearch.com/docs/learn/relevancy/custom_ranking_rules) we have more information available in our documentation. + +**And finally.. Sort & Custom ranking rules (NOT included in ranking score)** + +Its important to note that `Sort` ,`Asc/Desc` custom ranking rules will not be reflected in the Ranking Score. However if they are set, and how they are set, can affect your results. Heres what you need to know.. + +**Sort** + +The Sort rule only activates when you use the `sort` parameter in your search query. **Without that parameter, it has no effect.** + +When you do use `sort`, whatever you specify as a sort gets swapped into the Sort position in your ranking rules: + +Search query: + +```json +"q": "hello" +"sort": [ + "price:asc", + "author:desc" +] +``` + +Ranking rules: + +```json +[ + "words", + "typo", + "proximity", + "attribute", + "sort", // "price:asc" "author:desc" gets swapped in here + "exactness", + "release_date:asc", + "movie_ranking:desc" +] +``` + +**Key behaviour: Sort ignores text relevance** + +Sort and Custom ranking rules don't consider how well documents match your search query - they simply order results alphabetically or numerically by your chosen field (price, date, etc.). + +**Placement matters.** If you put Sort or Custom ranking rules at the top of your ranking rules, results will be ordered by that field instead of by text relevance. Apart from very specific use cases, such as price ordering, this usually creates a poor search experience where less relevant results appear first just because they have the right price or date. + +## Our Recommendations for Ranking Rule Ordering + +### Keep Group 1 rules first (Words, Typo, Proximity) + +Start with `words` as your first rule as it's the foundation. Every other rule depends on word matches existing, so it makes sense to establish those first. Follow it with `typo` and `proximity` to round out your broad matching. + +These three rules cast a wide net and pass a large pool of relevant results through the ranking chain. Starting broad is important. If you begin too narrow, you risk losing relevant documents before the later rules get a chance to refine them. + +### Place Sort strategically + +We recommend putting Sort after your Group 1 rules and before your Group 2 rules (Attribute, Exactness). This way, Meilisearch finds relevant results first and then uses your sort field to order documents that have similar text relevance, giving you a balance of match quality and sorting. + +If sorting matters more than text relevance for your use case - like an e-commerce price filter where users expect strict price ordering - move Sort higher. Just remember that Sort only activates when you include the `sort` parameter in your search query. Without it, the Sort rule has no effect. + +One thing to watch: placing Sort too late means most results are already in their final position before Sort gets a chance to act. If your sort field isn't influencing results the way you expect, try moving it up one position at a time and testing until you find the right spot. For a practical look at how this works, see [How Do I Interpret Ranking Score Details?](/guides/relevancy/interpreting_ranking_scores) where we show the same search returning different results just by moving Sort one position. + +### Use Custom ranking rules as tiebreakers + +Place custom ranking rules at the end of your sequence. They work best for adding business logic after text relevance has been established — things like popularity, recency, or user ratings. For example, if two recipes match equally well for "chicken curry," a custom `popularity:desc` rule can push the one with more saves to the top. + +### Going deeper + +Each ranking rule has its own settings you can fine-tune beyond just ordering. For example, you can adjust which fields take priority in attribute ranking, or configure how aggressively typo tolerance matches similar words. If you want to dig into the specifics: + +- [Built-in ranking rules](https://www.meilisearch.com/docs/learn/relevancy/ranking_rules#list-of-built-in-ranking-rules) — how each rule works and what it evaluates +- [Attribute ranking order](https://www.meilisearch.com/docs/learn/relevancy/attribute_ranking_order) — controlling which fields matter most +- [Typo tolerance settings](https://www.meilisearch.com/docs/learn/relevancy/typo_tolerance_settings) — adjusting how flexible matching behaves + +**Want to see these rules in action?** In our next guide, [How Do I Interpret Ranking Score Details?](/guides/relevancy/interpreting_ranking_scores), we walk through a real example showing exactly how Meilisearch evaluates each rule — and how moving Sort one position can flip your results. + +--- \ No newline at end of file From 29232b15d32d4bf3cab9592f64bc4777c02ff412 Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 10:39:47 +0000 Subject: [PATCH 02/11] removed asterisks from code blocks --- .../relevancy/interpreting_ranking_scores.mdx | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index db7466fdc..1259c83fc 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -35,7 +35,7 @@ Ranking Score details example "title": "Dragon", "overview": "In a desperate attempt to save her kingdom…", … - **"_rankingScoreDetails"**: { + "_rankingScoreDetails": { "words": { "order": 0, "matchingWords": 4, @@ -115,10 +115,10 @@ With this set up Meilisearch evaluates the text relevance rules first, *then* us "order": 0, "matchingWords": 2, "maxMatchingWords": 2, - **"score": 1.0** + "score": 1.0 }, - "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, "**score": 1.0** }, - "proximity": { "order": 2, "**score": 1.0** }, + "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, "score": 1.0 }, + "proximity": { "order": 2, "score": 1.0 }, "prep_time_minutes:asc": { "order": 3, "value": 20.0 }, "attribute": { "order": 4, @@ -151,10 +151,10 @@ With this set up Meilisearch evaluates the text relevance rules first, *then* us "order": 0, "matchingWords": 2, "maxMatchingWords": 2, - **"score": 1.0** + "score": 1.0 }, - "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, **"score": 1.0** }, - "proximity": { "order": 2, **"score": 0.5** }, + "typo": { "order": 1, "typoCount": 0, "maxTypoCount": 2, "score": 1.0 }, + "proximity": { "order": 2, "score": 0.5 }, "prep_time_minutes:asc": { "order": 3, "value": 15.0 }, "attribute": { "order": 4, @@ -209,7 +209,7 @@ Now let's move `sort` to the top of our ranking rules: "description": "A hearty stew with warming spices", "_rankingScore": 0.9149029982363316, "_rankingScoreDetails": { - **"prep_time_minutes:asc": { "order": 0, "value": 15.0 },** + "prep_time_minutes:asc": { "order": 0, "value": 15.0 }, "words": { "order": 1, "matchingWords": 2, @@ -245,7 +245,7 @@ Now let's move `sort` to the top of our ranking rules: "description": "A quick and simple chicken curry ready in 20 minutes", "_rankingScore": 0.9982363315696648, "_rankingScoreDetails": { - **"prep_time_minutes:asc": { "order": 0, "value": 20.0 },** + "prep_time_minutes:asc": { "order": 0, "value": 20.0 }, "words": { "order": 1, "matchingWords": 2, From 3638bc34d9427a7db31b92d68f408b9ea4f08022 Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 10:44:42 +0000 Subject: [PATCH 03/11] added link to other guide --- guides/relevancy/interpreting_ranking_scores.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index 1259c83fc..b11dd2070 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -281,7 +281,7 @@ Look at the `order` values. Sort is now `order: 0` so it runs first. Sort immediately separated the documents: 15 min beats 20 min. `:asc` will sort lowest to highest. Words, Typo, Proximity, and the rest never got a say. -Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs 0.914)** but it ranks second. This is exactly what the guide means when it says ranking score only measures text relevance. Sort affects the final order but doesn't change the score. If you only looked at `_rankingScore`, you'd think Doc 1 should be first. The score details tell you the real story. +Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs 0.914)** but it ranks second. This is exactly what we described in [Ordering ranking rules](/guides/relevancy/ordering_ranking_rules): ranking score only measures text relevance. Sort affects the final order but doesn't change the ranking score. If you only looked at `_rankingScore`, you'd think Doc 1 should be first. The score details tell you the real story. --- From e1cd76ea0d2db221fd0387f6691ea6b657026a4d Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 10:46:42 +0000 Subject: [PATCH 04/11] added clarification --- guides/relevancy/interpreting_ranking_scores.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index b11dd2070..25b303e35 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -286,8 +286,9 @@ Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs --- ## Side by Side +In both scenarios the user searches for `chicken curry`. -| | Scenario A (Sort placed after Group 1 ranking rules) | Scenario B (Sort placed first) | +| | Scenario A (Sort is placed after Group 1 ranking rules) | Scenario B (Sort is placed first) | | --- | --- | --- | | **#1 result** | Easy Chicken Curry (20 min) | Chicken Stew with Curry… (15 min) | | **Decided by** | Proximity (order 2) | Sort (order 0) | From 11dcd4a01face9c79d9ab5bbafcbb8cb4ade1648 Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 10:50:05 +0000 Subject: [PATCH 05/11] minor adjustment on scenario --- guides/relevancy/interpreting_ranking_scores.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index 25b303e35..3f5571b42 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -286,7 +286,7 @@ Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs --- ## Side by Side -In both scenarios the user searches for `chicken curry`. +In both scenarios the user searches for `"chicken curry"` and sorts by `prep_time_minutes:asc` (quickest first). The only change is the ranking rule placement. | | Scenario A (Sort is placed after Group 1 ranking rules) | Scenario B (Sort is placed first) | | --- | --- | --- | From d447c60c7f68c226798c63ce8b3bbf7950499295 Mon Sep 17 00:00:00 2001 From: gillian-meilisearch <132390895+gillian-meilisearch@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:06:37 +0000 Subject: [PATCH 06/11] Update guides/relevancy/interpreting_ranking_scores.mdx Co-authored-by: CaroFG <48251481+CaroFG@users.noreply.github.com> --- guides/relevancy/interpreting_ranking_scores.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index 3f5571b42..f3cb7dd14 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -3,7 +3,7 @@ title: Interpreting ranking score details description: Learn how to understand ranking score details to see how Meilisearch evaluates each result and which rules determined their order. --- -# How Do I Interpret Ranking Score Details? +# How do I interpret ranking score details? [In the previous guide](/guides/relevancy/ordering_ranking_rules), we covered how ranking rules determine result order and how changing their sequence affects what your users see first. But when you're actually making those tweaks, how do you know if they're working the way you expect? From a2cbcd029d6572896a19ff093d21600cdef9fb0f Mon Sep 17 00:00:00 2001 From: gillian-meilisearch <132390895+gillian-meilisearch@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:06:52 +0000 Subject: [PATCH 07/11] Update guides/relevancy/interpreting_ranking_scores.mdx Co-authored-by: CaroFG <48251481+CaroFG@users.noreply.github.com> --- guides/relevancy/interpreting_ranking_scores.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index f3cb7dd14..a3b46af9d 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -60,7 +60,7 @@ Ranking Score details example } ``` -# Ranking rules: Same Data, Different Results. How Sort Placement Changes Outcomes +# Ranking rules: same data, different results. How `sort` placement changes outcomes ## The Setup From 3291036345db83138c1fa9a2ef02991eeaba0db1 Mon Sep 17 00:00:00 2001 From: gillian-meilisearch <132390895+gillian-meilisearch@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:07:01 +0000 Subject: [PATCH 08/11] Update guides/relevancy/interpreting_ranking_scores.mdx Co-authored-by: CaroFG <48251481+CaroFG@users.noreply.github.com> --- guides/relevancy/interpreting_ranking_scores.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index a3b46af9d..4ee95a1df 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -62,7 +62,7 @@ Ranking Score details example # Ranking rules: same data, different results. How `sort` placement changes outcomes -## The Setup +## The setup You run a **recipe search app**. You have two recipes in your index: From 39ecff6bb990f4ffa32e8687a9e196a716b952f5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Wed, 11 Feb 2026 13:07:22 +0000 Subject: [PATCH 09/11] Update code samples [skip ci] --- ...ples_tenant_token_guide_generate_sdk_1.mdx | 56 +++++++++++++++++++ ...amples_tenant_token_guide_search_sdk_1.mdx | 23 ++++++++ 2 files changed, 79 insertions(+) create mode 100644 snippets/generated-code-samples/code_samples_tenant_token_guide_generate_sdk_1.mdx create mode 100644 snippets/generated-code-samples/code_samples_tenant_token_guide_search_sdk_1.mdx diff --git a/snippets/generated-code-samples/code_samples_tenant_token_guide_generate_sdk_1.mdx b/snippets/generated-code-samples/code_samples_tenant_token_guide_generate_sdk_1.mdx new file mode 100644 index 000000000..0893aee47 --- /dev/null +++ b/snippets/generated-code-samples/code_samples_tenant_token_guide_generate_sdk_1.mdx @@ -0,0 +1,56 @@ + + +```javascript JS +import { generateTenantToken } from 'meilisearch/token' + +const searchRules = { + patient_medical_records: { + filter: 'user_id = 1' + } +} +const apiKey = 'B5KdX2MY2jV6EXfUs6scSfmC...' +const apiKeyUid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76' +const expiresAt = new Date('2025-12-20') // optional + +const token = await generateTenantToken({ apiKey, apiKeyUid, searchRules, expiresAt }) +``` + +```python Python +uid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76'; +api_key = 'B5KdX2MY2jV6EXfUs6scSfmC...' +expires_at = datetime(2025, 12, 20) +search_rules = { + 'patient_medical_records': { + 'filter': 'user_id = 1' + } +} +token = client.generate_tenant_token(api_key_uid=uid, search_rules=search_rules, api_key=api_key, expires_at=expires_at) +``` + +```ruby Ruby +uid = '85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76' +api_key = 'B5KdX2MY2jV6EXfUs6scSfmC...' +expires_at = Time.new(2025, 12, 20).utc +search_rules = { + 'patient_medical_records' => { + 'filter' => 'user_id = 1' + } +} + +token = client.generate_tenant_token(uid, search_rules, api_key: api_key, expires_at: expires_at) +``` + +```go Go +searchRules := map[string]interface{}{ + "patient_medical_records": map[string]string{ + "filter": "user_id = 1", + }, +} +options := &meilisearch.TenantTokenOptions{ + APIKey: "B5KdX2MY2jV6EXfUs6scSfmC...", + ExpiresAt: time.Date(2025, time.December, 20, 0, 0, 0, 0, time.UTC), +} + +token, err := client.GenerateTenantToken(searchRules, options); +``` + \ No newline at end of file diff --git a/snippets/generated-code-samples/code_samples_tenant_token_guide_search_sdk_1.mdx b/snippets/generated-code-samples/code_samples_tenant_token_guide_search_sdk_1.mdx new file mode 100644 index 000000000..ca8ed4a7a --- /dev/null +++ b/snippets/generated-code-samples/code_samples_tenant_token_guide_search_sdk_1.mdx @@ -0,0 +1,23 @@ + + +```javascript JS +const frontEndClient = new MeiliSearch({ host: 'http://localhost:7700', apiKey: token }) +frontEndClient.index('patient_medical_records').search('blood test') +``` + +```python Python +front_end_client = Client('http://localhost:7700', token) +front_end_client.index('patient_medical_records').search('blood test') +``` + +```ruby Ruby +front_end_client = MeiliSearch::Client.new('http://localhost:7700', token) + +front_end_client.index('patient_medical_records').search('blood test') +``` + +```go Go +client := meilisearch.New("http://localhost:7700", meilisearch.WithAPIKey("masterKey")) +client.Index("patient_medical_records").Search("blood test", &meilisearch.SearchRequest{}); +``` + \ No newline at end of file From f359400e4783d0768281aa152e4b9fce9ba6b149 Mon Sep 17 00:00:00 2001 From: gillian-meilisearch <132390895+gillian-meilisearch@users.noreply.github.com> Date: Wed, 11 Feb 2026 13:09:40 +0000 Subject: [PATCH 10/11] Apply suggestions from code review Casing suggestions Co-authored-by: CaroFG <48251481+CaroFG@users.noreply.github.com> --- guides/relevancy/interpreting_ranking_scores.mdx | 8 ++++---- guides/relevancy/ordering_ranking_rules.mdx | 14 +++++++------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/guides/relevancy/interpreting_ranking_scores.mdx b/guides/relevancy/interpreting_ranking_scores.mdx index 4ee95a1df..8aec35cc7 100644 --- a/guides/relevancy/interpreting_ranking_scores.mdx +++ b/guides/relevancy/interpreting_ranking_scores.mdx @@ -91,7 +91,7 @@ Let's see how moving Sort **one position** in your ranking rules changes which r --- -## Scenario A: Sort placed AFTER Group 1 rules (recommended) +## Scenario A: `sort` placed AFTER Group 1 rules (recommended) We’ve set up our ranking rules to have sort after our Group 1 wide net rules. @@ -191,7 +191,7 @@ Also notice: Sort shows a `value` instead of a `score`. That's because Sort does --- -## Scenario B: Sort placed BEFORE Group 1 rules +## Scenario B: `sort` placed BEFORE Group 1 rules Now let's move `sort` to the top of our ranking rules: @@ -285,7 +285,7 @@ Notice something important: **Doc 1 still has a higher `_rankingScore` (0.998 vs --- -## Side by Side +## Side by side In both scenarios the user searches for `"chicken curry"` and sorts by `prep_time_minutes:asc` (quickest first). The only change is the ranking rule placement. | | Scenario A (Sort is placed after Group 1 ranking rules) | Scenario B (Sort is placed first) | @@ -298,7 +298,7 @@ In both scenarios the user searches for `"chicken curry"` and sorts by `prep_tim --- -## The Takeaway +## The takeaway Moving Sort **one position** flipped the results. The ranking score details let you see exactly why: diff --git a/guides/relevancy/ordering_ranking_rules.mdx b/guides/relevancy/ordering_ranking_rules.mdx index 1c1cf57d5..edbb94f33 100644 --- a/guides/relevancy/ordering_ranking_rules.mdx +++ b/guides/relevancy/ordering_ranking_rules.mdx @@ -3,9 +3,9 @@ title: Ordering ranking rules description: Learn how Meilisearch orders search results and how to customize ranking rule order for your use case. --- -# Ranking Rules: Getting the Order Right For You +# Ranking rules: getting the order right for you -**When to Read This Guide** +**When to read this guide** This guide is for you if you want to understand how Meilisearch orders your search results and how to customize that behavior for your specific use case. @@ -13,19 +13,19 @@ You might be here because you've noticed a document with a lower ranking score a **What you'll learn:** This guide explains how Meilisearch's ranking rules system works behind the scenes - how ranking scores relate to final result order, and how to adjust rankings to match your needs. You'll get practical tips and recommendations for common scenarios, so you can confidently tune your search results. -## **How Meilisearch Ranks Results** +## **How Meilisearch ranks results** -### **Ranking Score vs. Final Order** +### **Ranking score vs. final order** **Ranking score only measures text match quality.** It doesn't include Sort or Custom ranking rules. Ever noticed a document with a lower ranking score appearing higher in results? That's normal. The ranking score captures text relevance, but your final result order also includes Sort and Custom ranking rules, which don’t care for textual relevancy, and so these don't contribute to the ranking score. Understanding how these two work together is important to tweak effectively. -### **How Ranking Rules Work** +### **How ranking rules work** Meilisearch applies ranking rules sequentially. Each rule sorts documents into buckets and passes them to the next rule. This is why rule order matters - earlier rules take priority and later rules serve only as tie-breakers. -### Types of Ranking Rules +### Types of ranking rules **Group 1 - Broad matching: Word, Type, Proximity (included in ranking score)** @@ -50,7 +50,7 @@ If you want to dive deeper into the [built in ranking rules](https://www.meilise **And finally.. Sort & Custom ranking rules (NOT included in ranking score)** -Its important to note that `Sort` ,`Asc/Desc` custom ranking rules will not be reflected in the Ranking Score. However if they are set, and how they are set, can affect your results. Heres what you need to know.. +Its important to note that `sort` ,`asc/desc` custom ranking rules will not be reflected in the Ranking Score. However if they are set, and how they are set, can affect your results. Heres what you need to know.. **Sort** From a5eba2927f8a9d6487e3bbb207921430b3b7de2d Mon Sep 17 00:00:00 2001 From: Gillian McAuliffe Date: Wed, 11 Feb 2026 13:10:54 +0000 Subject: [PATCH 11/11] missing period in ellipsis --- guides/relevancy/ordering_ranking_rules.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/guides/relevancy/ordering_ranking_rules.mdx b/guides/relevancy/ordering_ranking_rules.mdx index edbb94f33..53e9b6822 100644 --- a/guides/relevancy/ordering_ranking_rules.mdx +++ b/guides/relevancy/ordering_ranking_rules.mdx @@ -48,7 +48,7 @@ This covers things like: If you want to dive deeper into the [built in ranking rules](https://www.meilisearch.com/docs/learn/relevancy/ranking_rules) and [custom ranking rules](https://www.meilisearch.com/docs/learn/relevancy/custom_ranking_rules) we have more information available in our documentation. -**And finally.. Sort & Custom ranking rules (NOT included in ranking score)** +**And finally... Sort & Custom ranking rules (NOT included in ranking score)** Its important to note that `sort` ,`asc/desc` custom ranking rules will not be reflected in the Ranking Score. However if they are set, and how they are set, can affect your results. Heres what you need to know..