{
    "slug": "search_relevance_tuning",
    "term": "Search Relevance Tuning",
    "category": "search",
    "difficulty": "advanced",
    "short": "Adjusting query-time ranking — field weights, boosts, and scoring functions — so the most useful documents rank highest for real queries.",
    "long": "Search relevance tuning is the practice of shaping query-time ranking without changing the underlying index or content. The index produces a base relevance score (usually BM25), but raw lexical scores rarely match user intent. Tuning layers signals on top of that score: per-field weights (title matches count more than body matches), query-time boosts (boost recent documents, in-stock products, or canonical pages), and custom scoring functions (decay by age, multiply by popularity, add a function score for distance). Most engines expose these as query parameters rather than index settings, so you can iterate on ranking quickly: Elasticsearch has function_score, field boosts (title^3), and rescore windows; Meilisearch has ranking rules and sortable attributes; Typesense has weights and sort_by expressions. Good tuning is data-driven. You start from real query logs, identify queries where the wanted result ranks low, and adjust signals while watching offline metrics (NDCG, MRR, precision@k) and online metrics (click-through rate, zero-result rate, conversion). The key discipline is changing one signal at a time and measuring, because boosts interact non-linearly: a strong recency boost can bury the single perfect old document. Over-tuning to a handful of pet queries causes regressions elsewhere, so a held-out judgement set or A/B test is essential. Tuning is also continuous — query patterns, catalogue, and user expectations drift, so relevance is a process, not a one-off configuration. Distinguish tuning from indexing: synonyms, stemming, and tokenisation are index-time concerns; weights, boosts, function scoring, and re-ranking are query-time concerns. This term covers the query-time half.",
    "aliases": [
        "relevance tuning",
        "ranking tuning",
        "query boosting",
        "score tuning"
    ],
    "tags": [
        "search",
        "relevance",
        "ranking",
        "bm25",
        "ndcg"
    ],
    "misconception": "Relevance is fixed by the search engine's default scoring and you cannot influence it without re-indexing — in reality most ranking adjustments are query-time parameters (boosts, field weights, function scores) that need no index changes.",
    "why_it_matters": "Poor ranking sends users to page two or to a competitor even when the right document is indexed; tuning weights and boosts can lift click-through and conversion with no content changes.",
    "common_mistakes": [
        "Tuning blindly without query logs or relevance judgements, so improvements for one query silently regress others.",
        "Stacking many boosts at once, making it impossible to tell which signal caused a ranking change.",
        "Using an extreme recency or popularity boost that overwhelms text relevance and buries the best match.",
        "Confusing index-time concerns (synonyms, stemming) with query-time tuning and re-indexing when a boost would do.",
        "Optimising only offline NDCG without validating against real user behaviour via A/B testing."
    ],
    "when_to_use": [
        "Users report the right result exists but ranks too low for common queries.",
        "Business signals like recency, popularity, or in-stock status should influence ordering.",
        "You have judged query sets or A/B infrastructure to measure ranking changes objectively.",
        "Exact title matches need to outrank incidental body matches across the catalogue."
    ],
    "avoid_when": [
        "The corpus is tiny and any reasonable ranking already satisfies users — tuning adds maintenance with no payoff.",
        "You have no query logs or relevance judgements yet, so changes cannot be measured and risk silent regressions.",
        "The real problem is missing recall (documents not matching at all), which is an indexing or analysis fix, not query-time tuning."
    ],
    "related": [
        "search_relevance",
        "bm25",
        "faceted_search",
        "meilisearch_typesense"
    ],
    "prerequisites": [
        "search_relevance",
        "bm25",
        "inverted_index"
    ],
    "refs": [
        "https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-function-score-query.html",
        "https://en.wikipedia.org/wiki/Discounted_cumulative_gain",
        "https://www.meilisearch.com/docs/learn/relevancy/relevancy"
    ],
    "bad_code": "// Flat query — every field weighted equally, no boosts:\n$results = $client->search('glossary', [\n    'q'    => $query,\n    'query_by' => 'term,short,long,category',\n]);\n// A keyword buried in the long body outranks an exact title match.\n// No recency, no popularity, no field priority — ranking is arbitrary.",
    "good_code": "// Query-time tuning: weighted fields + sort signals.\n// Typesense example — title matters most, then short, then body.\n$results = $client->collections['glossary']->documents->search([\n    'q'                   => $query,\n    'query_by'            => 'term,short,long',\n    'query_by_weights'    => '6,3,1',          // field boosts at query time\n    'sort_by'             => '_text_match:desc,popularity:desc', // tie-break by popularity\n    'prioritize_exact_match' => true,\n]);\n// Iterate: adjust weights, re-run against a judged query set,\n// compare NDCG@10, keep the change only if it improves.",
    "quick_fix": "Start from real query logs, change one ranking signal (field weight or boost) at a time, and measure NDCG or click-through before keeping it.",
    "severity": "medium",
    "effort": "medium",
    "created": "2026-06-04",
    "updated": "2026-06-04",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/search_relevance_tuning",
        "html_url": "https://codeclaritylab.com/glossary/search_relevance_tuning",
        "json_url": "https://codeclaritylab.com/glossary/search_relevance_tuning.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Search Relevance Tuning](https://codeclaritylab.com/glossary/search_relevance_tuning) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/search_relevance_tuning"
            }
        }
    }
}