All skills
Skillintermediate

Query DSL Reference

Full reference for Elasticsearch Query DSL query types. All examples assume `ES_URL` and `ES_API_KEY` are set.

Claude Code Knowledge Pack7/10/2026

Overview

Query DSL Reference

Full reference for Elasticsearch Query DSL query types. All examples assume ES_URL and ES_API_KEY are set.

Table of Contents

Full-Text Queries

match

Analyzes the query string and finds documents with matching terms:

{ "query": { "match": { "message": { "query": "error timeout", "operator": "and" } } } }
  • Default operator is or (any term matches)
  • Use "operator": "and" to require all terms
  • "fuzziness": "AUTO" enables typo tolerance

multi_match

Search across multiple fields:

{
  "query": {
    "multi_match": {
      "query": "connection refused",
      "fields": ["message", "error.message", "log.original"],
      "type": "best_fields"
    }
  }
}

Types: best_fields (default), most_fields, cross_fields, phrase, phrase_prefix

match_phrase

Matches exact phrase in order:

{ "query": { "match_phrase": { "message": "connection refused" } } }

match_phrase_prefix

Like match_phrase but last term is a prefix (autocomplete):

{ "query": { "match_phrase_prefix": { "message": "connect" } } }

query_string

Lucene syntax — powerful but can throw parse errors on bad input:

{ "query": { "query_string": { "query": "message:error AND level:critical", "default_field": "message" } } }

simple_query_string

Safer version — never throws parse errors, ignores invalid syntax:

{ "query": { "simple_query_string": { "query": "error + timeout -debug", "fields": ["message"] } } }

Operators: + (AND), | (OR), - (NOT), "..." (phrase), * (prefix), (...) (precedence)

Term-Level Queries

These operate on exact values (no analysis). Use on keyword, numeric, date, boolean fields.

term

Exact match on a single value:

{ "query": { "term": { "level": { "value": "error" } } } }

⚠️ Don't use term on text fields — they're analyzed, so exact match won't work as expected.

terms

Match any of several values (like SQL IN):

{ "query": { "terms": { "level": ["error", "critical", "fatal"] } } }

range

Numeric/date ranges:

{ "query": { "range": { "@timestamp": { "gte": "now-1h", "lt": "now" } } } }
{ "query": { "range": { "response_time": { "gte": 500, "lte": 5000 } } } }

Operators: gt, gte, lt, lte. Date math: now, now-1d, now/d (round to day).

exists

Field exists and has a non-null value:

{ "query": { "exists": { "field": "error.message" } } }

wildcard

Wildcard pattern matching (* = any chars, ? = single char):

{ "query": { "wildcard": { "hostname": { "value": "web-prod-*" } } } }

⚠️ Leading wildcards (*error) are expensive. Avoid in production.

regexp

Regular expression match:

{ "query": { "regexp": { "path": { "value": "/api/v[0-9]+/users.*" } } } }

prefix

Matches documents where field starts with value:

{ "query": { "prefix": { "hostname": { "value": "web-" } } } }

fuzzy

Typo-tolerant matching:

{ "query": { "fuzzy": { "message": { "value": "eror", "fuzziness": "AUTO" } } } }

ids

Match by document IDs:

{ "query": { "ids": { "values": ["doc-1", "doc-2", "doc-3"] } } }

Compound Queries

bool

Combine multiple queries with boolean logic:

{
  "query": {
    "bool": {
      "must":     [ { "match": { "message": "error" } } ],
      "filter":   [ { "range": { "@timestamp": { "gte": "now-1h" } } } ],
      "should":   [ { "term": { "level": "critical" } } ],
      "must_not": [ { "term": { "env": "dev" } } ],
      "minimum_should_match": 1
    }
  }
}
  • must — required, contributes to score
  • filter — required, does NOT contribute to score (faster, cacheable)
  • should — optional boost (or required if no must/filter)
  • must_not — excluded, does NOT contribute to score

Best practice: Put exact filters in filter, free-text in must.

boosting

Demote results matching a negative query without excluding them:

{
  "query": {
    "boosting": {
      "positive": { "match": { "message": "error" } },
      "negative": { "term": { "level": "debug" } },
      "negative_boost": 0.2
    }
  }
}

constant_score

Wrap a filter to return a fixed score:

{ "query": { "constant_score": { "filter": { "term": { "level": "error" } }, "boost": 1.0 } } }

function_score

Custom scoring functions (decay, random, field_value_factor):

{
  "query": {
    "function_score": {
      "query": { "match_all": {} },
      "functions": [
        { "field_value_factor": { "field": "popularity", "modifier": "log1p" } }
      ]
    }
  }
}

Nested & Join Queries

nested

Query nested objects (requires nested field type in mapping):

{
  "query": {
    "nested": {
      "path": "comments",
      "query": {
        "bool": {
          "must": [
            { "match": { "comments.author": "david" } },
            { "range": { "comments.date": { "gte": "now-7d" } } }
          ]
        }
      }
    }
  }
}

has_child / has_parent

Join queries for parent-child relationships:

{ "query": { "has_child": { "type": "answer", "query": { "match": { "body": "elasticsearch" } } } } }

Geo Queries

geo_bounding_box

{
  "query": {
    "geo_bounding_box": {
      "location": {
        "top_left": { "lat": 43.1, "lon": -79.0 },
        "bottom_right": { "lat": 42.8, "lon": -78.7 }
      }
    }
  }
}

geo_distance

{ "query": { "geo_distance": { "distance": "10km", "location": { "lat": 42.886, "lon": -78.878 } } } }

Special Queries

match_all / match_none

{ "query": { "match_all": {} } }
{ "query": { "match_none": {} } }

script

Custom scoring/filtering via Painless scripts:

{
  "query": {
    "script": {
      "script": {
        "source": "doc['response_time'].value > params.threshold",
        "params": { "threshold": 1000 }
      }
    }
  }
}

Search Features

Sorting

{ "sort": [ { "@timestamp": "desc" }, { "_score": "desc" } ] }

Source filtering

{ "_source": ["message", "level", "@timestamp"] }
{ "_source": { "includes": ["error.*"], "excludes": ["error.stack"] } }

Highlighting

{ "highlight": { "fields": { "message": { "pre_tags": [">>"], "post_tags": ["<<"] } } } }

search_after (pagination beyond 10k)

{
  "size": 100,
  "sort": [ { "@timestamp": "desc" }, { "_id": "asc" } ],
  "search_after": ["2026-01-31T12:00:00.000Z", "abc123"]
}

collapse (deduplicate by field)

{ "collapse": { "field": "hostname" }, "sort": [ { "@timestamp": "desc" } ] }

runtime fields (query-time computed fields)

{
  "runtime_mappings": {
    "duration_ms": {
      "type": "double",
      "script": "emit(doc['end_time'].value.toInstant().toEpochMilli() - doc['start_time'].value.toInstant().toEpochMilli())"
    }
  },
  "query": { "range": { "duration_ms": { "gte": 1000 } } }
}