Kibana Query Language (KQL) syntax reference
KQL (Kibana Query Language) is a text-based language for filtering documents by field values, ranges, wildcards, and combined conditions. You can use KQL syntax in:
- The Kibana query bar, for example in Discover and in dashboards.
- The Query DSL
kqlclause, for example in a_searchrequest. - The ES|QL
KQLfunction.
This page is the syntax reference, with examples you can adapt. The syntax is the same in all three places, with a few differences listed in Differences between Kibana and Elasticsearch. To learn what KQL is and where to use it, refer to the Kibana Query Language (KQL) overview.
Find the kind of condition you need in the table, then follow the link for details and examples.
| To find documents | Syntax | Example |
|---|---|---|
| Where a field exists | field: * |
http.request.method: * |
| That match a value | field: value |
http.request.method: GET |
That match an exact phrase in a text field |
field: "value" |
http.request.body.content: "null pointer" |
| With a value in any field | value |
Hello |
| Within a range | <, <=, >, >= |
http.response.bytes < 10000 |
| That match a pattern | * |
machine.os: win* |
| That don't match a condition | NOT |
NOT http.request.method: GET |
| That match several conditions | AND, OR, ( ) |
http.request.method: (GET OR POST OR DELETE) |
| With a value in one of several fields | field.*: value |
datastream.*: logs |
| With a matching nested field | field:{ condition } |
user:{ first: "Alice" AND last: "White" } |
To match documents that have an indexed value for a field, use * as the value. For example, documents where http.request.method exists:
http.request.method: *
This matches any indexed value, including an empty string.
To match a number, text, date, or boolean value, enter the field name, a colon, and the value. For example, documents where http.request.method is GET:
http.request.method: GET
On keyword, numeric, date, or boolean fields, the value must match exactly, including punctuation and case. To ignore case in keyword values, refer to Differences between Kibana and Elasticsearch.
On text fields, Elasticsearch analyzes the value using the field's mapping settings. For example, documents where http.request.body.content contains null pointer:
http.request.body.content: null pointer
Because this is a text field, the order of the search terms doesn't matter. Documents that contain pointer null also match. To match the terms in that order, surround the value with quotation marks:
http.request.body.content: "null pointer"
The field name is optional. If you leave it out, KQL searches a default set of fields. By default, that is every field that supports term queries, except metadata fields and nested fields. To change the fields, refer to Differences between Kibana and Elasticsearch. For example, to search for Hello in the default fields:
Hello
To use one of these characters in a value, escape it with a backslash, unless you surround the value with quotation marks:
\():<>"*{}
For example, either of these queries matches documents where http.request.referrer is https://example.com:
http.request.referrer: "https://example.com"
http.request.referrer: https\://example.com
Inside quotation marks, escape only the quotation mark and the backslash, as \" and \\. An asterisk inside quotation marks is a literal asterisk, not a wildcard.
The words AND, OR, and NOT are keywords (not case-sensitive). To use one as a value, escape it with a backslash, as in \AND, or surround it with quotation marks. Field names follow the same escaping rules as values.
To match values in a range, use <, <=, >, or >=. For example, documents where http.response.bytes is less than 10000:
http.response.bytes < 10000
For an inclusive range, combine two conditions. For example, documents where http.response.bytes is greater than 10000 and less than or equal to 20000:
http.response.bytes > 10000 AND http.response.bytes <= 20000
On multi-value fields, KQL tests each condition against every value in the array. number > 300 AND number < 400 matches "number": [500, 10]. The value 500 matches the first condition and 10 matches the second. If one value must satisfy every condition, use Query DSL.
You can also use range syntax with strings, IP addresses, and timestamps. For example, documents with a timestamp earlier than two weeks ago:
@timestamp < now-2w
A date that includes a time contains a colon, so surround it with quotation marks. For example, documents on or after 10:00 AM on January 1, 2021:
@timestamp >= "2021-01-01T10:00:00"
To set the time zone that KQL uses to interpret explicit dates, refer to Differences between Kibana and Elasticsearch.
For more examples of acceptable date formats, refer to Date Math.
To match a pattern, use a wildcard. Wildcards work on string-based fields, such as keyword, text, match_only_text, constant_keyword, flattened, and wildcard fields. On numeric, date, boolean, and ip fields, a wildcard makes the search fail with an error. KQL supports only *, which matches zero or more characters.
For example, documents where machine.os begins with win:
machine.os: win*
By default, you can put * at the start of a pattern. For example, documents where url contains elastic:
url: *elastic*
Queries that start with * can slow searches.
query:allowLeadingWildcards advanced setting.
To exclude documents, use the NOT keyword (not case-sensitive). For example, documents where http.request.method is not GET:
NOT http.request.method: GET
To exclude a group of conditions, put them in parentheses. For example, documents where http.request.method is neither GET nor POST:
NOT (http.request.method: GET OR http.request.method: POST)
To combine queries, use AND or OR (not case-sensitive). For example, documents where http.request.method is GET or http.response.status_code is 400:
http.request.method: GET OR http.response.status_code: 400
To require both conditions, use AND. For example, documents where http.request.method is GET and http.response.status_code is 400:
http.request.method: GET AND http.response.status_code: 400
To set precedence, use parentheses. For example, documents where http.request.method is GET and http.response.status_code is 200, or http.request.method is POST and http.response.status_code is 400:
(http.request.method: GET AND http.response.status_code: 200) OR
(http.request.method: POST AND http.response.status_code: 400)
In Kibana, without parentheses, NOT applies first, then AND, then OR. For example, this query matches GET requests, and also POST requests with status 400:
http.request.method: GET OR http.request.method: POST AND http.response.status_code: 400
In the Query DSL kql clause and the ES|QL KQL function, AND and OR have the same precedence and group from right to left. In those places, a: 1 AND b: 2 OR c: 3 means a: 1 AND (b: 2 OR c: 3). In Kibana, it means (a: 1 AND b: 2) OR c: 3. To get the same result everywhere, use parentheses.
To match several values on one field, put them in parentheses. For example, documents where http.request.method is GET, POST, or DELETE:
http.request.method: (GET OR POST OR DELETE)
Inside the parentheses, you can also use AND and NOT. For example, documents where tags contains production and doesn't contain deprecated:
tags: (production AND NOT deprecated)
To query several fields at once, use a wildcard in the field name. For example, documents where any subfield of datastream contains logs:
datastream.*: logs
The query can fail if the matching fields have different types. For example, if datastream.* matches both numeric and string fields, datastream.*: logs returns an error because you can't query numeric fields for string values.
Nested fields use a special syntax. In this JSON document, user is a nested field:
{
"user" : [
{
"first" : "John",
"last" : "Smith"
},
{
"first" : "Alice",
"last" : "White"
}
]
}
To find documents where a single value in the user array has the first name Alice and the last name White:
user:{ first: "Alice" AND last: "White" }
If nested fields contain other nested fields, use the full path of the field you want to query. In this JSON document, user and names are both nested fields:
{
"user": [
{
"names": [
{
"first": "John",
"last": "Smith"
},
{
"first": "Alice",
"last": "White"
}
]
}
]
}
To find documents where a single value in the user.names array has the first name Alice and the last name White:
user.names:{ first: "Alice" AND last: "White" }
The Kibana query bar, the Query DSL kql clause, and the ES|QL KQL function accept the same syntax. The following behaviors differ. Operator precedence also differs, as described in Combine multiple queries.
| Behavior | Kibana query bar | Query DSL kql clause and ES|QL KQL function |
|---|---|---|
Ignore case in keyword values |
Not available | Use the case_insensitive option. |
| Time zone for dates | The Time zone (dateFormat:tz) advanced setting |
Use the time_zone option. |
| Fields searched when you omit the field name | The index.query.default_field index setting |
The default_field option. If you don't set it, the index.query.default_field index setting. |
KQL function accepts these options in its options parameter. For the Query DSL kql clause, set them as parameters of the clause.