Understanding the Elasticsearch explain API
When relevance scores feel arbitrary and your top search results make no sense, the Elasticsearch explain API becomes your closest ally. The Elasticsearch explain API: practical tips and trade-offs shows you exactly why a document scored as it did, breaking down term frequencies, field boosts, query structure, and scoring formulas into readable pieces. Once you understand how to read an explanation, debugging relevance issues shifts from guesswork to precision engineering.
The explain parameter on search requests
The simplest way to use the explain API is adding explain=true to your search request. This tells Elasticsearch to include a detailed breakdown of the scoring calculation for every document in the response.
GET /products/_search
{
"explain": true,
"query": {
"match": {
"title": "wireless headphones"
}
},
"size": 10
}Each hit now includes an _explanation field that shows the scoring tree. For a simple match query, you might see term frequency (TF) contributions, inverse document frequency (IDF) weights, and field-length normalization all factored into the final score.
There's a trade-off here: enabling explain increases both query latency and response payload size. Elasticsearch must compute and serialize scoring details for every returned document. On a shard with millions of documents, this overhead compounds quickly. We typically enable explain only when actively investigating why a specific document ranked where it did, not on production traffic.
Reading term frequencies and boosts in explanations
The explanation output reveals two critical scoring factors: term frequency and field boosts.
Term frequency measures how often a search term appears in a document field. If you search for "headphones" and the word appears five times in one product's title but only once in another, the first product gets a higher TF contribution. The explanation shows this as termFreq=5 or similar, multiplied by the IDF weight.
Field boosts let you manually increase or decrease a field's contribution to the overall score. If your index has a boost configuration like this:
PUT /products
{
"mappings": {
"properties": {
"title": {
"type": "text",
"boost": 2.0
},
"description": {
"type": "text",
"boost": 1.0
}
}
}
}Then a match in title contributes twice as much to the score as a match in description, all else equal. The explanation will show this multiplier applied to the TF-IDF calculation.
A real scenario: your e-commerce team complains that a product with "headphones" in the description ranks higher than one with "headphones" in the title. Check the explanation. You might find that the description match has a higher term frequency, or perhaps a query-time boost is weighted differently than expected. Adjusting field boosts in your mapping or query structure, then re-explaining, lets you validate the fix before rolling it out.
Debugging relevance issues with explain
Relevance bugs are notoriously hard to track without visibility into scoring. Imagine users report that search for "red shoes" returns black shoes at the top. Your team suspects a field boost misconfiguration or a typo in a custom scoring script.
Use the explain API to compare the scoring breakdown for the black shoes result versus a red shoes result you know should rank higher:
GET /shoes/_explain/black-shoe-doc-id
{
"query": {
"multi_match": {
"query": "red shoes",
"fields": ["name^2", "description", "tags^0.5"]
}
}
}This returns the explanation for a single document. You'll see contributions from each field, weighted by the ^ boost syntax. If black shoes rank high despite having no match on "red", you've found your bug—perhaps the "description" field weight is too high, or there's a data quality issue where color metadata is missing.
Walk through the explanation tree methodically. Look for:
- Unexpected field contributions (e.g., description outweighing name).
- Missing matches on high-boost fields.
- Incorrect IDF values (suggesting tokenization or analyzer issues).
- Query clause weights that don't reflect your intent.
Once identified, adjust your query, mapping, or analyzer configuration, then re-run explain to confirm the fix improves the scoring.
Use explain on small result sets only
Production queries often return hundreds or thousands of documents. Enabling explain on all of them is wasteful. Instead, apply a focused strategy:
- Run your search normally without explain. Get the top 50–100 results to isolate candidates.
- Run explain on a subset. Add
explain=trueand reduce your result size to 5–10 documents. Focus on borderline cases (e.g., documents ranked 8–12 where you suspect a bug). - Compare explanations side-by-side. Write a small script to pretty-print two explanations so you can spot differences in scoring logic.
Here's a practical pattern we use when investigating scoring regressions:
GET /products/_search
{
"explain": true,
"query": {
"bool": {
"must": [
{
"match": {
"title": "wireless"
}
}
]
}
},
"size": 5,
"track_scores": true
}By setting size to 5 and using a constrained query (e.g., a bool query with high-precision filters), we minimize the overhead while getting detailed visibility into the scores that matter.
Common mistakes
Mistake 1: Running explain on production with size set to 10,000. This causes severe latency spikes. Always combine explain with a small size limit or run it on a test cluster.
Mistake 2: Misinterpreting boosts in the explanation. A boost of 2.0 doesn't mean a document will score exactly twice as high; it's one factor among many. IDF, TF, field length, and query structure all interact. Read the entire explanation tree, not just the final number.
Mistake 3: Assuming explain output is deterministic across shards. If your index has multiple shards, the same query can produce slightly different explanations due to per-shard IDF calculations. Use a single-shard test index or review shard statistics when debugging across a real cluster.
Mistake 4: Forgetting to check the query structure itself. Sometimes low scores aren't due to boosting misconfiguration but because your query logic is wrong. Review what terms are actually being searched and whether they're combined with AND or OR.
Key takeaways
- Add
explain=trueto your search request to see the scoring breakdown for each document. - Focus on term frequency (TF) and field boosts (both index-time and query-time) as the primary scoring levers you'll tune.
- Use explain on a small, targeted result set to avoid query latency and network overhead in production.
- Read the full explanation tree; scoring is a composite of multiple factors, not a single number.
- Compare explanations between documents you expected to rank differently to isolate the root cause of relevance bugs.
- Remember that boosts, IDF, and field length normalization all interact; changes to one factor ripple through the score.






Comments
Loading comments…