skip to content

In Elasticsearch, how do the ^ field-boost suffix and the boost parameter affect _score?

level: juniorimportance: must knowfreq 72%

answer

  1. It is a multiplier, not a filter
  2. Only the ratio between boosts matters
  3. Scaling every boost changes no ordering
  4. Some bool clauses never score at all
  5. Filter context and constant_score ignore it

basics

~20 s

A boost is a multiplier on one query clause's score contribution: title^3 inside a multi_match triples what a title match adds, and any query's boost parameter does the same. Boosts are relative weights, and filter context ignores them.

solid answer

~50 s

A boost is a multiplier applied to the score a single clause produces. In `multi_match` or `query_string` you write it per field — `"fields": ["title^3", "body"]` — and essentially every query type also accepts an explicit `boost` parameter. Because a `bool` query combines the scores of its matching clauses, `title^3` means the title clause contributes about three times as much to that combination, not that the final `_score` triples. Boosts are purely relative: `title^3, body^1` ranks identically to `title^6, body^2`, because every score is scaled by the same constant. Values between 0 and 1 shrink a clause. Boosts are positive multipliers, so to push matches down rather than remove them you use the `boosting` query's `negative_boost`. A boost inside filter context — a `filter` or `must_not` clause, or `constant_score` — does nothing, because those clauses contribute no score. Index-time boosting through the mapping `boost` parameter is deprecated; boost at query time instead.

code

json · 8 lines
json
{
  "query": {
    "multi_match": {
      "query": "kafka rebalance",
      "fields": ["title^3", "tags^2", "body"]
    }
  }
}

go deeper

for a junior

Be ready to read a multi_match field list aloud and say what title^3 means, and to write the same thing with an explicit boost parameter on a match query.

for a middle

Explain that clause scores are combined arithmetically, so only boost ratios matter and doubling every boost changes nothing. Know that filter context does not score, so boosts there are ignored.

for a senior

Show how you tune boosts empirically against a judged query set rather than by intuition, and explain why raw BM25 scores from a short title and a long body are not comparable to begin with.

for a principal

Own the position that boosts are a blunt, hand-maintained instrument: argue when a team should stop adding boost constants and move the signal into a learned or feature-based ranking stage instead.

## What a boost actually is A boost is a plain multiplier applied to the relevance score that one query clause produces. Elasticsearch scores a document by running the scoring queries in the request — each produces a number, BM25 for text queries — and combining them. A boost changes one of those numbers before the combination happens. It does not filter, it does not guarantee an ordering, and it does not make a field "more important" in any absolute sense. It only reweights one contribution inside an arithmetic sum. ## Where you write one There are two syntaxes for the same idea. The caret suffix is a shorthand available in the field lists of `multi_match`, `query_string` and `simple_query_string`: ```json { "multi_match": { "query": "kafka", "fields": ["title^3", "body"] } } ``` The explicit parameter is accepted by nearly every query type and is the general form: ```json { "bool": { "should": [ { "match": { "title": { "query": "kafka", "boost": 3 } } }, { "match": { "body": "kafka" } } ]}} ``` A field with no suffix has boost 1. Both forms do the same thing; the caret is just terser. ## Boosts are relative, not absolute The single most common misunderstanding is treating a boost as a percentage or as a rank guarantee. Neither holds. If a `bool` sums a title clause scoring 2.0 and a body clause scoring 5.0, boosting title by 3 gives 6.0 + 5.0 = 11.0. The title contribution now leads, but a document whose body match is exceptionally strong can still win. Boosting is a nudge on a continuous scale, never a hard tier. Because the combination is linear, multiplying every boost by the same constant changes nothing about the ordering. `title^3, body^1` and `title^6, body^2` produce the same ranking with all scores doubled. Only the *ratio* between boosts matters. This is why absolute score values are not comparable across queries and why chasing a particular `_score` number is a wasted afternoon. Values below 1 are legal and useful: `body^0.5` halves the body clause rather than tripling everything else. Boosts are positive multipliers. When you want to demote a match — documents mentioning "trial version" should rank lower but still appear — the tool is the `boosting` query, which takes a `positive` query, a `negative` query and a `negative_boost` factor between 0 and 1 that multiplies the score of documents matching the negative side. ## Filter context silently ignores boosts Clauses in a `bool`'s `filter` or `must_not` arrays, and anything wrapped in `constant_score`, run in filter context: Elasticsearch answers only "does this match?", skips scoring entirely, and can reuse the cached result. A `boost` written on such a clause is accepted and has no effect on ranking. Candidates who move a clause into `filter` for speed and keep its boost are usually surprised when relevance stops responding. If a signal must influence ranking it has to be in query context (`must` or `should`). ## Why per-field boosting is coarse A per-field boost multiplies the whole clause, so it inherits everything BM25 already did — term frequency, inverse document frequency and the field-length norm. Two fields with wildly different lengths and vocabularies do not produce comparable raw scores, so a boost of 3 on a short `title` and a long `body` is not "three times as important", it is "three times whatever title happened to score". This is why tuning boosts is empirical: change the ratio, measure against judged queries, repeat. It also explains why `multi_match` types matter — `best_fields` takes the maximum clause score via `dis_max`, `most_fields` sums them — and the same boost behaves differently under each. ## Index-time boosting is not the answer Older Elasticsearch let you set a `boost` in the mapping so a field's boost was folded into the stored norm at index time. That is deprecated in current versions and was always a poor trade: the boost was stored with very low precision inside a single-byte norm, it could not be changed without reindexing, and it silently interacted with length normalisation. Query-time boosting costs nothing extra and can be changed per request, which is what you want while you are still tuning. ## Practical guidance Start with 1 everywhere, raise one field at a time, and keep the ratios small — 2 to 5 is a normal range, and boosts of 100 usually mean someone is trying to express a hard ordering that belongs in a sort or a filter. Verify with a judged query set rather than by eyeballing one search, and remember that a boost only matters for documents that actually match the boosted clause: boosting `title` does nothing for a document whose title does not contain the query term.

  • If a boost is just a multiplier, why does raising it sometimes not change the result order at all?
    Because the boosted clause has to match for the multiplier to apply. If every document in the result set matches the boosted clause with similar strength, scaling that contribution scales everyone alike and the order is untouched. Boosts only separate documents when the boosted clause discriminates between them.
  • How do you demote documents that match an unwanted term instead of excluding them?
    Use the `boosting` query: put the main query in `positive`, the unwanted condition in `negative`, and set `negative_boost` to a fraction such as 0.2. Documents matching the negative side keep appearing but have their score multiplied down. A `must_not` clause would remove them entirely, which is a different product decision.
  • Does a boost change which documents match?
    No. Boosting is purely a scoring operation; the matching set is identical with boost 1 or boost 50. Only the order and the score values change, which is why boosting cannot rescue a query whose analysis chain never produced a match in the first place.

A boost is a weight on one judge's vote in a panel, not a veto. Tripling one judge's weight shifts the outcome but cannot stop a unanimous panel from outvoting them.

saying these in an interview costs you the question

  • Says boost is a percentage increase in the final score
  • Claims a high boost guarantees that field's matches rank first
  • Puts a boost on a bool filter clause and expects ranking to change
  • Uses a negative boost value to demote instead of the boosting query
  • Sets boosts in the mapping so ranking requires a reindex

context