---
title: "Query DSL Reference"
description: "Full reference for Elasticsearch Query DSL query types. All examples assume `ES_URL` and `ES_API_KEY` are set."
type: skill
canonical_url: https://claudary.paisolsolutions.com/skills/query-dsl
source: "Claudary"
difficulty: intermediate
author: "Claude Code Knowledge Pack"
date: 2026-07-10T11:37:22.807Z
license: CC-BY-4.0
attribution: "Query DSL Reference — Claudary (https://claudary.paisolsolutions.com/skills/query-dsl)"
---

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

## 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](#full-text-queries)
- [Term-Level Queries](#term-level-queries)
- [Compound Queries](#compound-queries)
- [Nested & Join Queries](#nested--join-queries)
- [Geo Queries](#geo-queries)
- [Special Queries](#special-queries)
- [Search Features](#search-features)

## Full-Text Queries

### match

Analyzes the query string and finds documents with matching terms:

```json
{ "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:

```json
{
  "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:

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

### match_phrase_prefix

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

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

### query_string

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

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

### simple_query_string

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

```json
{ "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:

```json
{ "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`):

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

### range

Numeric/date ranges:

```json
{ "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:

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

### wildcard

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

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

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

### regexp

Regular expression match:

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

### prefix

Matches documents where field starts with value:

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

### fuzzy

Typo-tolerant matching:

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

### ids

Match by document IDs:

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

## Compound Queries

### bool

Combine multiple queries with boolean logic:

```json
{
  "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:

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

### constant_score

Wrap a filter to return a fixed score:

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

### function_score

Custom scoring functions (decay, random, field_value_factor):

```json
{
  "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):

```json
{
  "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:

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

## Geo Queries

### geo_bounding_box

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

### geo_distance

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

## Special Queries

### match_all / match_none

```json
{ "query": { "match_all": {} } }
{ "query": { "match_none": {} } }
```

### script

Custom scoring/filtering via Painless scripts:

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

## Search Features

### Sorting

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

### Source filtering

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

### Highlighting

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

### search_after (pagination beyond 10k)

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

### collapse (deduplicate by field)

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

### runtime fields (query-time computed fields)

```json
{
  "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 } } }
}
```

---

Source: [Claudary](https://claudary.paisolsolutions.com/skills/query-dsl) · https://claudary.paisolsolutions.com
