NEW

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

Elasticsearch Prefix Query: Syntax, Parameters, and Examples - Syntax, Example, and Tips

The Elasticsearch prefix query matches documents that contain at least one indexed term starting with a given string. It runs against the term dictionary, so behavior depends on the field's analyzer: on keyword fields it matches the full value, on analyzed text fields it matches per-token prefixes. The query is classified as expensive by default but becomes cheap when the field has the index_prefixes mapping option enabled - in that case it bypasses the search.allow_expensive_queries restriction.

Syntax

GET /index/_search
{
  "query": {
    "prefix": {
      "field_name": {
        "value": "lap",
        "case_insensitive": false,
        "rewrite": "constant_score"
      }
    }
  }
}

Parameters

Parameter Description Required Default
value Prefix to search for. Yes -
case_insensitive ASCII case-insensitive matching. Available since Elasticsearch 7.10. No false
rewrite Multi-term rewrite method (constant_score, top_terms_N, etc.). No constant_score

A short-form syntax also exists: {"prefix": {"field_name": "lap"}} is equivalent to the longer form with default options.

Examples

Basic prefix match on a keyword field:

GET /products/_search
{
  "query": {
    "prefix": {
      "product_name.keyword": {
        "value": "lap"
      }
    }
  }
}

Case-insensitive prefix:

GET /users/_search
{
  "query": {
    "prefix": {
      "email": {
        "value": "John.",
        "case_insensitive": true
      }
    }
  }
}

Use the field's index_prefixes for cheap autocomplete (define the mapping option at index creation):

PUT /products
{
  "mappings": {
    "properties": {
      "title": {
        "type": "text",
        "index_prefixes": { "min_chars": 2, "max_chars": 5 }
      }
    }
  }
}

GET /products/_search
{
  "query": {
    "prefix": {
      "title": { "value": "wir" }
    }
  }
}

Combine with a filter to prune the candidate set first:

GET /products/_search
{
  "query": {
    "bool": {
      "filter": [ { "term": { "category": "phones" } } ],
      "must":   [ { "prefix": { "model.keyword": "iph" } } ]
    }
  }
}

Performance and Use Notes

Prefix queries walk the slice of the term dictionary that starts with the given string. On a sorted dictionary that slice is found by binary search, then iterated. Cost grows with the number of matching terms, not with index size. For autocomplete on large indices, the index_prefixes mapping option pre-indexes prefixes between min_chars (default 2) and max_chars (default 5) at index time; queries within that length range execute as single term lookups.

Prefix queries are considered expensive by default and are rejected when search.allow_expensive_queries: false - unless the field uses index_prefixes, in which case they are exempt. On analyzed text fields, the prefix is matched against tokens after analysis; on keyword fields, against the unanalyzed value. Pick the right sub-field to match user expectations.

Slow autocomplete is a frequent driver of search latency complaints. The manual triage - identifying prefix queries running on fields without index_prefixes, then chasing each one back to the originating service - is the loop Pulse runs continuously.

Common Mistakes

  1. Running prefix queries on analyzed text fields and getting per-token matches instead of starts-with-string semantics. Use the .keyword sub-field.
  2. Implementing autocomplete with plain prefix queries on a multi-million-document index instead of index_prefixes, search_as_you_type, or a completion suggester.
  3. Forgetting that prefix ignores case_insensitive on field types without ASCII semantics (full Unicode lowercasing requires a normalizer or analyzer).
  4. Allowing one-character prefixes from user input on large indices - the candidate set can include hundreds of thousands of terms.
  5. Expecting search.allow_expensive_queries: false to block prefix queries on index_prefixes fields. It does not - those are exempt.

Optimize Slow Prefix Queries with Pulse

Pulse is an AI DBA for Elasticsearch and OpenSearch that continuously profiles production query traffic. For prefix queries specifically, Pulse:

  • Identifies prefix queries running against fields without the index_prefixes mapping option, where the term-dictionary slice scan dominates latency
  • Flags prefix queries rejected by search.allow_expensive_queries: false because the field is not exempt, plus the services still attempting them
  • Spots one-character prefixes from user input that are enumerating hundreds of thousands of terms on large indices
  • Traces each slow prefix query back to the calling service via slow-log and APM correlation
  • Recommends the right mapping change for the use case: add index_prefixes with appropriate min_chars / max_chars, migrate to search_as_you_type, switch to a completion suggester for autocomplete, or use match_phrase_prefix for multi-word input
  • Tracks latency improvement after the mapping change ships

This converts the manual slow-log plus mapping-review loop into a continuous optimization workflow.

Try Pulse on your cluster.

Frequently Asked Questions

Q: How is a prefix query different from a wildcard query?
A: A prefix query matches terms that start with a fixed string and is optimized by the sorted term dictionary. A wildcard query accepts * and ? anywhere, and a leading wildcard forces a full term scan. Use prefix whenever the pattern is "starts with X".

Q: What does the index_prefixes mapping option do?
A: It pre-indexes term prefixes between min_chars and max_chars (defaults 2 and 5) into a sidecar field. Prefix queries that fall in that length range turn into a single term lookup instead of a term-dictionary slice scan, and they are exempt from the search.allow_expensive_queries cap.

Q: How do I make a prefix query case-insensitive?
A: Set case_insensitive: true on the query (Elasticsearch 7.10+). For older clusters or non-ASCII data, index the field with a lowercase normalizer (for keyword) or a lowercasing analyzer (for text) and lowercase the input value.

Q: How is a prefix query different from match_phrase_prefix?
A: A prefix query matches a single term's prefix. `match_phrase_prefix` takes a multi-word phrase, requires the leading terms to match exactly, and uses prefix matching only on the last term. It is the standard query for "search as you type" multi-word input.

Q: Can I use a prefix query on numeric fields?
A: It works syntactically because numeric fields are converted to their string form, but the result is rarely useful. Use a range query for numeric, date, or IP fields.

Q: Are prefix queries cacheable?
A: Yes, in filter context. They enter the per-node query cache like other constant-score queries, so repeated identical prefixes are cheap after the first execution.

Q: What is the best tool to find slow prefix queries powering autocomplete?
A: Pulse profiles Elasticsearch and OpenSearch slow logs, identifies prefix queries running without index_prefixes on large fields, attributes each one to the calling service, and recommends the mapping change - index_prefixes, search_as_you_type, or a completion suggester - that fits the access pattern.

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.