[[kuery-query]]
=== Kuery

experimental[This functionality is experimental and may be changed or removed completely in a future release.]

Kuery is a new query language built specifically for Kibana. It aims to simplify the search experience in Kibana
and enable the creation of helpful features like auto-complete, seamless migration of saved searches, additional
query types, and more. Kuery is a basic experience today but we're hard at work building these additional features on
top of the foundation Kuery provides.

Kueries are built with functions. Many functions take a field name as their first argument. Extremely common functions have shorthand notations.

`is("response", 200)` will match documents where the response field matches the value 200.
`response:200` does the same thing. `:` is an alias for the `is` function.

Multiple search terms are separated by whitespace.

`response:200 extension:php` will match documents where response matches 200 and extension matches php.

*All terms must match by default*. The language supports boolean logic with and/or operators. The above query is equivalent to `response:200 and extension:php`.
This is a departure from the Lucene query syntax where all terms are optional by default.

We can make terms optional by using `or`.

`response:200 or extension:php` will match documents where response matches 200, extension matches php, or both.

By default, `and` has a higher precedence than `or`.

`response:200 and extension:php or extension:css` will match documents where response is 200 and extension is php OR documents where extension is css and response is anything.

We can override the default precedence with grouping.

`response:200 and (extension:php or extension:css)` will match documents where response is 200 and extension is either php or css.

Terms can be inverted by prefixing them with `!`.

`!response:200` will match all documents where response is not 200.

Entire groups can also be inverted.

`response:200 and !(extension:php or extension:css)`

Some query functions have named arguments.

`range("bytes", gt=1000, lt=8000)` will match documents where the bytes field is greater than 1000 and less than 8000.

Quotes are generally optional if your terms don't have whitespace or special characters. `range(bytes, gt=1000, lt=8000)`
would also be a valid query.

[NOTE]
============
Terms without fields will be matched against all fields. For example, a query for `response:200` will search for the value 200
in the response field, but a query for just `200` will search for 200 across all fields in your index.
============

==== Function Reference

[horizontal]
Function Name::  Description

and:: 
Purpose::: Match all given sub-queries
Alias::: `and` as a binary operator
Examples::: 
* `and(response:200, extension:php)`
* `response:200 and extension:php`

or::
Purpose::: Match one or more sub-queries
Alias::: `or` as a binary operator
Examples::: 
* `or(extension:css, extension:php)`
* `extension:css or extension:php`

not::
Purpose::: Negates a sub-query
Alias::: `!` as a prefix operator
Examples:::
* `not(response:200)` 
* `!response:200`

is::
Purpose::: Matches a field with a given term
Alias::: `:`
Examples::: 
* `is("response", 200)`
* `response:200`

range::
Purpose::: Match a field against a range of values.
Alias::: `:[]`
Examples::: 
* `range("bytes", gt=1000, lt=8000)`
* `bytes:[1000 to 8000]`
Named arguments:::
* `gt` - greater than
* `gte` - greater than or equal to
* `lt` - less than
* `lte` - less than or equal to

exists::
Purpose::: Match documents where a given field exists
Examples::: `exists("response")`

geoBoundingBox::
Purpose::: Creates a geo_bounding_box query
Examples:::
* `geoBoundingBox("coordinates", topLeft="40.73, -74.1", bottomRight="40.01, -71.12")` (whitespace between lat and lon is ignored)
Named arguments:::
* `topLeft` - the top left corner of the bounding box as a "lat, lon" string
* `bottomRight` - the bottom right corner of the bounding box as a "lat, lon" string

geoPolygon::
Purpose::: Creates a geo_polygon query given 3 or more points as "lat, lon"
Examples::: 
* `geoPolygon("geo.coordinates", "40.97, -127.26", "24.20, -84.375", "40.44, -66.09")`