Elasticsearch Elasticsearch Constant Score Query

By Opster Team

Updated: Jan 28, 2024

| 3 min read

Quick links

Introduction and background

Elasticsearch has a comprehensive Query DSL (Domain Specific Language) that is based on JSON for defining queries. The query DSL uses two separate types of clauses: leaf query clauses and compound query clauses.

  • Leaf query clauses – Like match, term, and range queries, leaf query clauses look for a specific value in a particular field. These queries can be used by themselves.
  • Compound query clauses –  these change the behavior of other compound or leaf queries, combine their results, and/or switch the context from the query to the filter. You can logically combine many queries, such as the bool and dis_max queries, or change the behavior of many queries by using compound queries, such as the constant_score and boosting queries.

The constant_score query wraps other queries by executing them in a filter context. 

The identical “constant” _score is given for all matching documents.

Relevance scores, query context and filter context

By default, Elasticsearch groups relevant search results based on relevance score, which determines how closely each document matches the query (what was searched). The relevance score is represented by a positive floating point value in the search API’s _score metadata field. 

The higher the _score is, the more relevant the document is. The calculation of the relevance score also relies on whether the query clause is executed in a query or filter context, even though relevance scores for every query type can be calculated differently. Query clauses can behave differently based on whether they are used in a query context or a filter context.

A query clause responds to the inquiry “How well does this document match this query clause?” in the query context. The _score metadata field’s relevance score is calculated by the query clause, which also decides if the document matches. Once a query clause is supplied to a query parameter, such as the query parameter in the search API, query context is in effect. 

In a filter context, a query clause provides an answer to the question “Does this document match this query clause?” The answer is simple. Only Yes or No; no scores are computed. 

The filter context is most frequently used to filter structured data. To enhance efficiency, Elasticsearch will automatically cache frequently used filters. Filter context is active when a query clause is provided to a filter parameter, like the filter aggregation, the filter parameter in a constant_score query, or the filter or must_not parameters in a bool query.

Structured data and full-text queries are both supported by Elasticsearch. Structured searches do not need scoring, whereas full-text queries do in order to locate the best matching documents by using the scoring mechanisms. We can change a scoring query, which typically executes in a query context, into a non-scoring filter context by using the constant_score query. 

The constant_score query retrieves all matching documents with a relevance score equal to the boost parameter value after wrapping a filter query.

When should you use a constant score query?

A constant_score query gives an equal score to any matching document. This can be used when, unlike a filter, you don’t care how much a document matched, but simply whether it matched or not, and also provides a score. A boost parameter is used by the constant_score query to be set as the score for each matching document.

How to implement a constant score query

Constant score queries have two top-level parameters, which are:

  • filter: a required query object parameter that represents the filter query that you want to run, all the returned documents need to match this query. Relevance scores are not calculated for filter queries. Elasticsearch automatically caches frequently used filter queries to improve performance.
  • boost: an optional parameter of type float that represents a floating point number that is used as the constant relevance score for each document that matches the filter query. Its default value is 1.0.

The following is the general structure of a constant score query:

GET index_name/_search
{
  "query": {
    "constant_score": {
      "filter": {
         "match" : {"<field_name>" : "<your_value>"}
      },
      "boost": float number that you want to use as a constant score for every matching document 
    }
  }
}

The match query is typically executed in a query context, this means that when Elasticsearch runs a match query, it scores all of the documents in addition to filtering them. When the constant score query is used as shown in the example below, the scoring query is changed, which typically executes in a query context, into a non-scoring filter context. 

The constant score query will retrieve all matching documents (in this case, that have the value “Elie” in the author_name field) with a relevance score equal to the boost parameter value which is 1.2 after wrapping a filter query.

GET authors/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "match": { "author_name": "Elie" }
      },
      "boost": 1.2
    }
  }
}

Filter clauses are performed in the filter context, therefore scoring is disregarded and clauses are considered for caching.

A constant_score filter should wrap a match query if we wish to accelerate it and cache it. Use this strategy if you don’t care about the relevance score, as demonstrated in the example below.

GET authors/_search
{
    "query": {
        "constant_score" : {
            "filter" : {
                "match": { "author": "Elie" }
            }
        }
    }
}

The query is now quicker because no relevance score is calculated any longer. It is also automatically cached.

To sum up, the constant_score query changes any query into the filter context with a relevance score equal to the boost parameter value, its default value is 1.

Notes and good things to know

  • Scores are computed as single precision floating point values with just 24 bits of precision for the significand when queries are used in query context. Score calculations that are greater than the precision of the significand will be converted to floats, however, with some precision lost.
  • Use query context just for conditions that should have an influence on the score of documents that match (i.e., how closely the document matches) and filter context for all other query clauses.