Find out why a result ranked where it did
This guide shows you how to inspect the relevance score of a document for a search query, trace score calculations back to query clauses, inspect ranking signal contributions, identify why a document is missing, and explain sub-document hits. Use this guide when you need to defend or tune the result ordering in your catalogue.
Prerequisites
Section titled “Prerequisites”Before you begin, ensure that you have:
- An index with a declared primary key.
- An API token with the
searchpermission. - The primary key of the document you want to explain.
-
Send your search query to the explain endpoint:
Save your search request body to a file named
search.json:{"query": [{ "type": "text", "text": "waterproof boot", "fields": { "name": 3 } },{ "type": "boost", "weight": 2, "clauses": [{ "field": "category", "match": { "value": "boots" } }] }],"filters": [{ "field": "inStock", "match": { "value": true } }]}Run
curlto post the search request to the explain action, passing the document’s primary key in thekeyquery parameter:Terminal window curl -X POST \"$EXOFIND/v1alpha1/indexes/products/search/actions/explain?key=9781234567890" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \--data @search.jsonThe endpoint compiles the same clauses, locale, and index settings as the search endpoint. Parameters such as
limit,offset,sort,facets, andhighlightare ignored. If your search specifies a field sort, the endpoint still calculates and explains the relevance score. -
Map score contributions back to your request clauses:
Inspect the
detailobject in the JSON response to see how each clause contributed to the total score:{"matched": true,"score": 7.42,"detail": {"matched": true,"score": 7.42,"description": "sum of:","children": [{"matched": true,"score": 5.10,"description": "weight(name:waterproof) ...","clause": "query[0]","clauseType": "text","field": "name","usage": "matching","children": []}]}}Each node in
childrenincludes:clause: The path to the clause in your request body (for example,query[0],query[1].clauses[0], orfilters[0]).clauseType: The clause type from your request, such astext,boost,field,knn, orfuse.field: The field name defined in your index definition.score: The numeric score contributed by this clause to the parent step.
-
Identify why a document is missing from results:
If a document does not appear in search results, send the search body with the document’s
keyto the explain endpoint.When a document does not match the search, the response returns
matched: falseandscore: 0:{"matched": false,"score": 0,"detail": {"matched": false,"score": 0,"description": "sum of:","children": [{"matched": true,"score": 3.2,"clause": "query[0]"},{"matched": false,"score": 0,"clause": "filters[0]","clauseType": "field","field": "inStock"}]}}Check the
matchedboolean on each child step:- Steps with
"matched": truesatisfied the condition. - Steps with
"matched": falsefailed the condition and caused the document to be excluded.
- Steps with
-
Inspect ranking signal contributions:
If your search or index includes ranking signals, locate the
signalschild node in thedetailtree:{"matched": true,"score": 1.30,"description": "signals, product of:","children": [{"matched": true,"score": 1.24,"description": "signal popularity (saturation, pivot 10.0, weight 1.0) reads 412.0","children": []}]}Each ranking signal step reports the name of the field it reads, its mathematical shape and weight, and the raw value read from the document. If a document has no value in that field, the ranking signal reports a multiplier score of
1. -
Explain a sub-document or value hit:
When your search targets sub-documents using
"hits": { "path": "<field>" }, pass the zero-based index of the sub-document in theindexquery parameter:Terminal window curl -X POST \"$EXOFIND/v1alpha1/indexes/products/search/actions/explain?key=9781234567890&index=1" \-H "Authorization: Bearer $KEY" \-H "Content-Type: application/json" \--data @search.jsonThe
keyparameter identifies the parent document, and theindexparameter selects the specific sub-document value to explain.
Confirming the result
Section titled “Confirming the result”Inspect the response from the explain endpoint to confirm the scoring breakdown:
matched:trueif the document matches the query and filters;falseif it was excluded.score: The total relevance score calculated for the hit.detail: The hierarchical score tree containing descriptions, scores, andclausepointers.relaxed: Present if query terms were dropped during search relaxation. Contains the dropped words and the actual query text evaluated.
Related
Section titled “Related”- Search API - Request bodies, clauses, matchers, and parameters.
- Relevance - How scoring and ranking signals determine result order.
- Tuning ranking - Changing the order the explain output reports on.
- Searching an index - Constructing search requests and filter clauses.
- Using sub-documents - Querying and scoring individual object values.
- Errors - Error codes returned by index actions.
Exofind is built by Level Four AB and is available under the Apache License 2.0.