Match query

Match query #

Returns documents that match a provided text, number, date or boolean value. The provided text is analyzed before matching — this is the primary full-text query.

Inside a nested query: supported — the text is matched per array element.

How it works #

The engine resolves the analyzer first — the analyzer parameter when given, else the field’s search analyzer, else the built-in standard analyzer — and runs it over the query text. Each resulting token becomes one term clause:

  • operator: "or" (default) — the term posting lists are unioned. A document matches when it contains any token, and its score is the sum of the BM25 scores of the tokens it contains.
  • operator: "and" — the posting lists are intersected. A document must contain every token; a token missing from the dictionary makes the whole query match nothing, while under or the missing token is simply dropped.

A single-token query runs on a dedicated single-term producer; multi-token AND cursors are sorted rarest-first so the intersection drives from the shortest posting list. Scores are BM25 with k1 = 1.2 and b = 0.75:

idf   = ln(1 + (N - df + 0.5) / (df + 0.5))
score = idf * tf * (k1 + 1) / (tf + k1 * (1 - b + b * dl / avgdl))

N counts the documents that have the field, df is the term’s document frequency, tf its frequency in the matched document, dl the document’s raw token count (stored as a quantized field norm), and avgdl the field’s total tokens over N — guarded to 1.0 for an empty field. Cross-segment queries correct per-segment IDF to the global statistics, so a term scores the same wherever its document lives.

When the field is not analyzed text, a rewrite happens first: a match on a keyword, numeric, date or boolean field becomes an exact term lookup — the field’s normalizer applied when configured — instead of tokenizing. boost multiplies into the BM25 chain; fuzziness is rejected outright (see parameters below).

Examples #

POST /my-collection/_search
{
  "query": {
    "match": {
      "field": "message",
      "query": "this is a test"
    }
  }
}

The match query applies the field’s search analyzer (or analyzer when given) to the text, then matches the resulting tokens with OR semantics by default. Require all tokens with operator. Below, the single token search finds the GET /search lines — 25 of the 150 documents:

POST /my-collection/_search
{
  "query": {
    "match": {
      "field": "message",
      "query": "this is a test",
      "operator": "and"
    }
  }
}

Use cases #

  • The search box. Free-typed user input is the canonical match: analyzed, OR-ed, BM25-ranked. In the logs dataset all 25 messages carrying cluster node left contain the full phrase, so or and and return the same 25 documents — the operator dial only matters once words scatter across documents.
  • A precision dial. operator: "and" switches the same query text from “any word” to “every word” — the strict mode of the same box.
  • Exact values without a term query. On keyword, numeric, date or boolean fields the rewrite to a term lookup means one query shape serves both analyzed text and structured fields.
  • Typo tolerance — deliberately elsewhere. fuzziness is rejected with a 400 rather than silently ignored; use the fuzzy query or query_string’s ~.

Parameters for match #

  • field
    (Required, string) Field you wish to search.

  • query
    (Required, string) Text, number, boolean value or date you wish to find in the provided field.

  • analyzer
    (Optional, string) Analyzer used to convert the text in the query value into tokens. Defaults to the field’s search analyzer.

  • operator
    (Optional, string) Boolean logic used to interpret the text: or (default) or and.

  • minimum_should_match
    (Optional, string) Minimum number of clauses that must match for a document to be returned.

  • fuzziness
    (unsupported) Fuzzy matching inside match is not implemented. Setting fuzziness is rejected with HTTP 400 naming the parameter, rather than silently ignored — a body carrying it would otherwise run as an exact analyzed match, which is not what the writer intended. Use the fuzzy query or the query_string ~ operator instead:

    POST /my-collection/_search
    { "query": { "match": { "field": "title", "query": "hello", "fuzziness": "AUTO" } } }
    # 400 — match.fuzziness is not supported yet — use the `fuzzy` query
    #       (or the query_string `~` operator) instead
    
  • prefix_length
    (Optional, integer, default: 0) Number of beginning characters left unchanged for fuzzy matching.

  • max_expansions
    (Optional, integer, default: 50) Maximum number of terms to which the query expands.

  • fuzzy_transpositions
    (Optional, boolean, default: true) Edits for fuzzy matching include transpositions of two adjacent characters (ab → ba).

  • auto_generate_synonyms_phrase_query
    (Optional, boolean, default: true) If true, match phrase queries are automatically created for multi-term synonyms.

  • lenient
    (Optional, boolean, default: false) If true, format-based errors (such as a text value for a numeric field) are ignored.

  • boost
    (Optional, float, default: 1.0) Decrease or increase the relevance scores of the query.

  • fuzzy_rewrite
    (Optional, string) Method used to rewrite the fuzzy expansion (constant_score, scoring_boolean, …).

  • zero_terms_query
    (Optional, string) What to match when the analyzer removes every token (e.g. a stop filter): none (default, matches nothing) or all.

  • cross_fields_strategy
    (Optional, string) Score combination used when one field name resolves to several analyzed sub-fields: most_fields (sum — the default) or best_fields (max).

  • multi_match — the same analyzed matching fanned out over several fields, with per-field boosts.
  • phrase — when the order of the tokens matters as much as their presence.
  • bool — combines match clauses with filters and exclusions; every compound query ends up a bool.
  • Analyzers — what produces the tokens that match matches on.
  • API conventions — request envelope and strict-gate parameter handling.
Calendar October 6, 2026
Edit Edit this page