KQL

The Kibana Query Language (KQL) is a text-based query language for filtering data.

  • KQL only filters data. It does not aggregate, transform, or sort data.
  • KQL is different from the Lucene query language. Lucene has a different feature set.

Use KQL to filter documents by field existence, value, or range.

To compare KQL with Query DSL, ES|QL, and other languages, refer to Query languages.

Combine free text search with field-based search using KQL. Enter a term to match across all fields. Start typing a field name to get suggestions for fields and operators.

Query type Example
Exact phrase query http.response.body.content.text:"quick brown fox"
Multiple values http.response.status_code: (400 OR 401 OR 404)
Boolean query response:200 or extension:php
Range query account_number >= 100 and items_sold <= 200
Wildcard query machine.os:win*

To match any of several values on one field, use parentheses and OR. For the full syntax, refer to Combining multiple queries.

To find documents where a field has an indexed value, use *. For example, documents where http.request.method exists:

http.request.method: *
		

This matches any indexed value, including an empty string.

Use KQL to match a number, text, date, or boolean value. For example, documents where http.request.method is GET:

http.request.method: GET
		

The field name is optional. If you omit it, KQL searches all fields for the given value. For example, to search all fields for “Hello”:

Hello
		

On keyword, numeric, date, or boolean fields, the value must match exactly, including punctuation and case.

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 these search terms does not matter. Documents that contain “pointer null” also match. To search text fields for terms in that order, surround the value in quotation marks:

http.request.body.content: "null pointer"
		

Escape certain characters with a backslash, unless you surround the value with quotes. For example, either of these queries matches http.request.referrer https://example.com:

http.request.referrer: "https://example.com"
http.request.referrer: https\://example.com
		

Escape these characters:

\():<>"*
		

To find values in a range, use KQL range syntax. For example, http.response.bytes less than 10000:

http.response.bytes < 10000
		

For an inclusive range, combine conditions. For example, bytes 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]. 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 for strings, IP addresses, and timestamps. For example, documents earlier than two weeks ago:

@timestamp < now-2w
		

For more examples on acceptable date formats, refer to Date Math.

To match a pattern, use a wildcard. You can use wildcards on keyword, text, and wildcard fields. They do not work on numeric, date, or boolean fields.

For example, machine.os values that begin with "win":

machine.os: win*
		

Only * is supported. It matches zero or more characters.

By default, you can put * at the start of a pattern. For example, url values that contain elastic:

url: *elastic*
		

Queries that start with * can slow searches.

To avoid that, turn leading wildcards off with the 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 combine queries, use AND or OR (not case-sensitive). For example, GET requests or responses with status 400:

http.request.method: GET OR http.response.status_code: 400
		

To require both conditions, use AND:

http.request.method: GET AND http.response.status_code: 400
		

Use parentheses to set precedence. This example matches GET requests with status 200, or POST requests with status 400:

(http.request.method: GET AND http.response.status_code: 200) OR
(http.request.method: POST AND http.response.status_code: 400)
		

You can also use parentheses to match several values on one field. For example, GET, POST, or DELETE:

http.request.method: (GET OR POST OR DELETE)
		

You can also use wildcards to query multiple fields. For example, documents where any sub-field of datastream contains “logs”:

datastream.*: logs
		

If the matching fields have different types, the query can fail. For example, if datastream.* matches both numeric and string fields, datastream.*: logs returns an error. You cannot query numeric fields for string values.

Nested fields use a special syntax. Consider this document, where user is nested:

{
  "user" : [
    {
      "first" : "John",
      "last" :  "Smith"
    },
    {
      "first" : "Alice",
      "last" :  "White"
    }
  ]
}
		

To find a user array value with first name “Alice” and last name “White”:

user:{ first: "Alice" and last: "White" }
		

If nested fields contain other nested fields, use the full path. Consider this document, where user and names are both nested:

{
  "user": [
    {
      "names": [
        {
          "first": "John",
          "last": "Smith"
        },
        {
          "first": "Alice",
          "last": "White"
        }
      ]
    }
  ]
}
		

To find a user.names array value with first name “Alice” and last name “White”:

user.names:{ first: "Alice" and last: "White" }