NEW

Pulse 2025 Product Roundup: From Monitoring to AI-Native Control Plane

Elasticsearch Constant Score Query: Filter With a Fixed Score - Syntax, Example, and Tips

The Elasticsearch constant_score query wraps a filter clause and assigns every matching document the same score, equal to the boost parameter (default 1.0). It is the canonical way to use a filter inside a scoring query context without producing a meaningful relevance score. Use it when you need a filter to contribute a known, fixed contribution to a combined bool score, or to suppress BM25 scoring on a clause that should be a pure include/exclude check.

Syntax

{
  "query": {
    "constant_score": {
      "filter": { /* any filter clause */ },
      "boost":  1.0
    }
  }
}

Parameters

Parameter Type Default Description
filter query - Filter clause that selects matching documents. Required.
boost float 1.0 Constant score assigned to every matching document.

filter accepts any query clause. The wrapped clause runs in filter context: no scoring, results cacheable as a bitset.

Examples

Assign a constant score to documents marked as featured:

GET /products/_search
{
  "query": {
    "constant_score": {
      "filter": { "term": { "featured": true } },
      "boost":  1.5
    }
  }
}

Combine with full-text scoring inside a bool - the constant_score clause adds a flat boost to recent items on top of the BM25 score:

GET /articles/_search
{
  "query": {
    "bool": {
      "should": [
        { "match": { "body": "kafka tuning" } },
        { "constant_score": {
            "filter": { "range": { "published_at": { "gte": "now-7d" } } },
            "boost":  2.0
        }}
      ]
    }
  }
}

Wrap a complex filter to keep score predictable:

GET /events/_search
{
  "query": {
    "constant_score": {
      "filter": {
        "bool": {
          "must":     [ { "term":  { "type": "purchase" } } ],
          "must_not": [ { "term":  { "refunded": true } } ],
          "filter":   [ { "range": { "amount": { "gte": 100 } } } ]
        }
      }
    }
  }
}

Replace expensive scoring on a known-good filter with a fixed score:

GET /logs/_search
{
  "query": {
    "constant_score": {
      "filter": { "term": { "tenant_id": "acme" } }
    }
  }
}

Performance and Use Notes

The wrapped filter runs in filter context regardless of where constant_score appears, which means its result bitset is cacheable in the node-level query cache. That is the primary performance benefit: a clause that would otherwise be in a bool.must (query context, scored, uncached) becomes cacheable.

For most "filter + no score" use cases, the more idiomatic form is bool.filter rather than constant_score. bool.filter produces a final score of 0.0 for the clause and is what the official Elasticsearch documentation recommends. Reach for constant_score specifically when you need the matching documents to contribute a non-zero, predictable amount to a combined score.

Filter caching strategy directly drives Elasticsearch cluster throughput. Pulse monitors filter-cache hit ratios, evictions, and cache memory usage on your Elasticsearch cluster, and surfaces queries where rewriting must into filter or constant_score would shift load off the scoring path.

Common Mistakes

  1. Using constant_score in bool.filter - filter context already implies score 0, and wrapping with constant_score does not produce a non-zero score there.
  2. Setting an aggressive boost (e.g. 100) and overpowering all other scored clauses in the parent bool.
  3. Reaching for constant_score when bool.filter is the simpler, idiomatic choice.
  4. Wrapping a match query and losing all relevance signal from the analyzed text - if you wanted relevance, do not use constant_score.
  5. Assuming constant_score disables filter caching - it does not; the inner filter is still cacheable.

Frequently Asked Questions

Q: What is the difference between constant_score and bool filter in Elasticsearch?
A: bool.filter runs clauses in filter context and contributes 0 to the combined score. constant_score also runs the inner clause in filter context but contributes a fixed non-zero score equal to its boost. Use constant_score when the filter should add a known amount to the parent bool's score; use bool.filter when score is irrelevant.

Q: Does constant_score use the filter cache?
A: Yes. The wrapped filter executes in filter context, so its bitset is eligible for the node-level query cache. This is the main performance reason to prefer constant_score over running the same predicate in a must clause.

Q: How does the boost parameter work in a constant_score query?
A: Every document matching the inner filter receives a score equal to boost (default 1.0). The boost is the entire score - no BM25, no field-length normalization, no inverse document frequency.

Q: When should I prefer constant_score over wrapping a filter directly?
A: When the filter clause needs to contribute a non-zero score, typically inside a bool.should where it combines with full-text matches. If you do not need a score from the clause at all, bool.filter is more idiomatic.

Q: Can I use constant_score with full-text queries?
A: You can, but the relevance score from the full-text query is discarded - every match gets the same constant score. That defeats the purpose of full-text scoring, so reach for function_score if you need both relevance and custom scoring.

Q: What happens if I omit the filter parameter from constant_score?
A: The query is invalid and Elasticsearch returns a parse error. filter is required.

Subscribe to the Pulse Newsletter

Get early access to new Pulse features, insightful blogs & exclusive events , webinars, and workshops.

We use cookies to provide an optimized user experience and understand our traffic. To learn more, read our use of cookies; otherwise, please choose 'Accept Cookies' to continue using our website.