| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497 | [role="xpack"][testenv="basic"][[sql-rest]]== SQL REST API* <<sql-rest-overview>>* <<sql-rest-format>>* <<sql-pagination>>* <<sql-rest-filtering>>* <<sql-rest-columnar>>* <<sql-rest-fields>>[[sql-rest-overview]]=== OverviewThe SQL REST API accepts SQL in a JSON document, executes it,and returns the results. For example:[source,console]--------------------------------------------------POST /_sql?format=txt{    "query": "SELECT * FROM library ORDER BY page_count DESC LIMIT 5"}--------------------------------------------------// TEST[setup:library]Which returns:[source,text]--------------------------------------------------     author      |        name        |  page_count   | release_date-----------------+--------------------+---------------+------------------------Peter F. Hamilton|Pandora's Star      |768            |2004-03-02T00:00:00.000ZVernor Vinge     |A Fire Upon the Deep|613            |1992-06-01T00:00:00.000ZFrank Herbert    |Dune                |604            |1965-06-01T00:00:00.000ZAlastair Reynolds|Revelation Space    |585            |2000-03-15T00:00:00.000ZJames S.A. Corey |Leviathan Wakes     |561            |2011-06-02T00:00:00.000Z--------------------------------------------------// TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]// TESTRESPONSE[non_json][[sql-kibana-console]].Using Kibana ConsoleIf you are using {kibana-ref}/console-kibana.html[Kibana Console](which is highly recommended), take advantage of thetriple quotes `"""` when creating the query. This not only automatically escapes doublequotes (`"`) inside the query string but also support multi-line as shown below:image:images/sql/rest/console-triple-quotes.png[][[sql-rest-format]]=== Response Data FormatsWhile the textual format is nice for humans, computers prefer somethingmore structured.{es-sql} can return the data in the following formats which can be seteither through the `format` property in the URL or by setting the `Accept` HTTP header:NOTE: The URL parameter takes precedence over the `Accept` HTTP header.If neither is specified then the response is returned in the same format as the request.[cols="^m,^4m,^8"]|===s|formats|`Accept` HTTP headers|Description3+h| Human Readable|csv|text/csv|https://en.wikipedia.org/wiki/Comma-separated_values[Comma-separated values]|json|application/json|https://www.json.org/[JSON] (JavaScript Object Notation) human-readable format|tsv|text/tab-separated-values|https://en.wikipedia.org/wiki/Tab-separated_values[Tab-separated values]|txt|text/plain|CLI-like representation|yaml|application/yaml|https://en.wikipedia.org/wiki/YAML[YAML] (YAML Ain't Markup Language) human-readable format3+h| Binary Formats|cbor|application/cbor|http://cbor.io/[Concise Binary Object Representation]|smile|application/smile|https://en.wikipedia.org/wiki/Smile_(data_interchange_format)[Smile] binary data format similar to CBOR|===Here are some examples for the human readable formats:==== CSV[source,console]--------------------------------------------------POST /_sql?format=csv{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,text]--------------------------------------------------author,name,page_count,release_datePeter F. Hamilton,Pandora's Star,768,2004-03-02T00:00:00.000ZVernor Vinge,A Fire Upon the Deep,613,1992-06-01T00:00:00.000ZFrank Herbert,Dune,604,1965-06-01T00:00:00.000ZAlastair Reynolds,Revelation Space,585,2000-03-15T00:00:00.000ZJames S.A. Corey,Leviathan Wakes,561,2011-06-02T00:00:00.000Z--------------------------------------------------// TESTRESPONSE[non_json]==== JSON[source,console]--------------------------------------------------POST /_sql?format=json{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,console-result]--------------------------------------------------{    "columns": [        {"name": "author",       "type": "text"},        {"name": "name",         "type": "text"},        {"name": "page_count",   "type": "short"},        {"name": "release_date", "type": "datetime"}    ],    "rows": [        ["Peter F. Hamilton",  "Pandora's Star",       768, "2004-03-02T00:00:00.000Z"],        ["Vernor Vinge",       "A Fire Upon the Deep", 613, "1992-06-01T00:00:00.000Z"],        ["Frank Herbert",      "Dune",                 604, "1965-06-01T00:00:00.000Z"],        ["Alastair Reynolds",  "Revelation Space",     585, "2000-03-15T00:00:00.000Z"],        ["James S.A. Corey",   "Leviathan Wakes",      561, "2011-06-02T00:00:00.000Z"]    ],    "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="}--------------------------------------------------// TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]==== TSV[source,console]--------------------------------------------------POST /_sql?format=tsv{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,text]--------------------------------------------------author	name	page_count	release_datePeter F. Hamilton	Pandora's Star	768	2004-03-02T00:00:00.000ZVernor Vinge	A Fire Upon the Deep	613	1992-06-01T00:00:00.000ZFrank Herbert	Dune	604	1965-06-01T00:00:00.000ZAlastair Reynolds	Revelation Space	585	2000-03-15T00:00:00.000ZJames S.A. Corey	Leviathan Wakes	561	2011-06-02T00:00:00.000Z--------------------------------------------------// TESTRESPONSE[s/\t/ /]// TESTRESPONSE[non_json]==== TXT[source,console]--------------------------------------------------POST /_sql?format=txt{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,text]--------------------------------------------------     author      |        name        |  page_count   |      release_date      -----------------+--------------------+---------------+------------------------Peter F. Hamilton|Pandora's Star      |768            |2004-03-02T00:00:00.000ZVernor Vinge     |A Fire Upon the Deep|613            |1992-06-01T00:00:00.000ZFrank Herbert    |Dune                |604            |1965-06-01T00:00:00.000ZAlastair Reynolds|Revelation Space    |585            |2000-03-15T00:00:00.000ZJames S.A. Corey |Leviathan Wakes     |561            |2011-06-02T00:00:00.000Z--------------------------------------------------// TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]// TESTRESPONSE[non_json]==== YAML[source,console]--------------------------------------------------POST /_sql?format=yaml{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,yaml]--------------------------------------------------columns:- name: "author"  type: "text"- name: "name"  type: "text"- name: "page_count"  type: "short"- name: "release_date"  type: "datetime"rows:- - "Peter F. Hamilton"  - "Pandora's Star"  - 768  - "2004-03-02T00:00:00.000Z"- - "Vernor Vinge"  - "A Fire Upon the Deep"  - 613  - "1992-06-01T00:00:00.000Z"- - "Frank Herbert"  - "Dune"  - 604  - "1965-06-01T00:00:00.000Z"- - "Alastair Reynolds"  - "Revelation Space"  - 585  - "2000-03-15T00:00:00.000Z"- - "James S.A. Corey"  - "Leviathan Wakes"  - 561  - "2011-06-02T00:00:00.000Z"cursor: "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="--------------------------------------------------// TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/][[sql-pagination]]=== Paginating through a large responseUsing the example above, one can continue to the next page by sending back the `cursor` field. Incase of text format the cursor is returned as `Cursor` http header.[source,console]--------------------------------------------------POST /_sql?format=json{    "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f///w8="}--------------------------------------------------// TEST[continued]// TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f\/\/\/w8=/$body.cursor/]Which looks like:[source,console-result]--------------------------------------------------{    "rows" : [        ["Dan Simmons",        "Hyperion",             482,  "1989-05-26T00:00:00.000Z"],        ["Iain M. Banks",      "Consider Phlebas",     471,  "1987-04-23T00:00:00.000Z"],        ["Neal Stephenson",    "Snow Crash",           470,  "1992-06-01T00:00:00.000Z"],        ["Frank Herbert",      "God Emperor of Dune",  454,  "1981-05-28T00:00:00.000Z"],        ["Frank Herbert",      "Children of Dune",     408,  "1976-04-21T00:00:00.000Z"]    ],    "cursor" : "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWODRMaXBUaVlRN21iTlRyWHZWYUdrdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl9f///w8="}--------------------------------------------------// TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWODRMaXBUaVlRN21iTlRyWHZWYUdrdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl9f\/\/\/w8=/$body.cursor/]Note that the `columns` object is only part of the first page.You've reached the last page when there is no `cursor` returnedin the results. Like Elasticsearch's <<request-body-search-scroll,scroll>>,SQL may keep state in Elasticsearch to support the cursor. Unlikescroll, receiving the last page is enough to guarantee that theElasticsearch state is cleared.To clear the state earlier, you can use the clear cursor command:[source,console]--------------------------------------------------POST /_sql/close{    "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f///w8="}--------------------------------------------------// TEST[continued]// TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f\/\/\/w8=/$body.cursor/]Which will like return the[source,console-result]--------------------------------------------------{    "succeeded" : true}--------------------------------------------------[[sql-rest-filtering]]=== Filtering using {es} query DSLYou can filter the results that SQL will run on using a standard{es} query DSL by specifying the query in the filterparameter.[source,console]--------------------------------------------------POST /_sql?format=txt{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "filter": {        "range": {            "page_count": {                "gte" : 100,                "lte" : 200            }        }    },    "fetch_size": 5}--------------------------------------------------// TEST[setup:library]Which returns:[source,text]--------------------------------------------------    author     |                name                |  page_count   | release_date---------------+------------------------------------+---------------+------------------------Douglas Adams  |The Hitchhiker's Guide to the Galaxy|180            |1979-10-12T00:00:00.000Z--------------------------------------------------// TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]// TESTRESPONSE[non_json][[sql-rest-columnar]]=== Columnar resultsThe most well known way of displaying the results of an SQL query result in general is the one where eachindividual record/document represents one line/row. For certain formats, {es-sql} can return the resultsin a columnar fashion: one row represents all the values of a certain column from the current page of results.The following formats can be returned in columnar orientation: `json`, `yaml`, `cbor` and `smile`.[source,console]--------------------------------------------------POST /_sql?format=json{    "query": "SELECT * FROM library ORDER BY page_count DESC",    "fetch_size": 5,    "columnar": true}--------------------------------------------------// TEST[setup:library]Which returns:[source,console-result]--------------------------------------------------{    "columns": [        {"name": "author", "type": "text"},        {"name": "name", "type": "text"},        {"name": "page_count", "type": "short"},        {"name": "release_date", "type": "datetime"}    ],    "values": [        ["Peter F. Hamilton", "Vernor Vinge", "Frank Herbert", "Alastair Reynolds", "James S.A. Corey"],        ["Pandora's Star", "A Fire Upon the Deep", "Dune", "Revelation Space", "Leviathan Wakes"],        [768, 613, 604, 585, 561],        ["2004-03-02T00:00:00.000Z", "1992-06-01T00:00:00.000Z", "1965-06-01T00:00:00.000Z", "2000-03-15T00:00:00.000Z", "2011-06-02T00:00:00.000Z"]    ],    "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="}--------------------------------------------------// TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]Any subsequent calls using a `cursor` still have to contain the `columnar` parameter to preserve the orientation,meaning the initial query will not _remember_ the columnar option.[source,console]--------------------------------------------------POST /_sql?format=json{    "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8=",    "columnar": true}--------------------------------------------------// TEST[continued]// TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]Which looks like:[source,console-result]--------------------------------------------------{    "values": [        ["Dan Simmons", "Iain M. Banks", "Neal Stephenson", "Frank Herbert", "Frank Herbert"],        ["Hyperion", "Consider Phlebas", "Snow Crash", "God Emperor of Dune", "Children of Dune"],        [482, 471, 470, 454, 408],        ["1989-05-26T00:00:00.000Z", "1987-04-23T00:00:00.000Z", "1992-06-01T00:00:00.000Z", "1981-05-28T00:00:00.000Z", "1976-04-21T00:00:00.000Z"]    ],    "cursor": "46ToAwFzQERYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQUVXWjBaNlFXbzNOV0pVY21Wa1NUZDJhV2t3V2xwblp3PT3/////DwQBZgZhdXRob3IBBHRleHQAAAFmBG5hbWUBBHRleHQAAAFmCnBhZ2VfY291bnQBBGxvbmcBAAFmDHJlbGVhc2VfZGF0ZQEIZGF0ZXRpbWUBAAEP"}--------------------------------------------------// TESTRESPONSE[s/46ToAwFzQERYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQUVXWjBaNlFXbzNOV0pVY21Wa1NUZDJhV2t3V2xwblp3PT3\/\/\/\/\/DwQBZgZhdXRob3IBBHRleHQAAAFmBG5hbWUBBHRleHQAAAFmCnBhZ2VfY291bnQBBGxvbmcBAAFmDHJlbGVhc2VfZGF0ZQEIZGF0ZXRpbWUBAAEP/$body.cursor/][[sql-rest-fields]]=== Supported REST parametersIn addition to the `query` and `fetch_size`, a request a number of user-defined fields for specifyingthe request time-outs or localization information (such as timezone).The table below lists the supported parameters:[cols="^m,^m,^5"]|===s|names|Default values|Description|query|Mandatory|SQL query to execute|fetch_size|1000|The maximum number of rows (or entries) to return in one response|filter|none|Optional {es} query DSL for additional <<sql-rest-filtering, filtering>>.|request_timeout|90s|The timeout before the request fails.|page_timeout|45s|The timeout before a pagination request fails.|time_zone|`Z` (or `UTC`)|Time-zone in ISO 8601 used for executing the query on the server.More information available https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html[here].|columnar|false|Return the results in a columnar fashion, rather than row-based fashion. Valid for `json`, `yaml`, `cbor` and `smile`.|field_multi_value_leniency|false|Throw an exception when encountering multiple values for a field (default) or be lenient and return the first value from the list (without any guarantees of what that will be - typically the first in natural ascending order).|index_include_frozen|false|Whether to include <<frozen-indices, frozen-indices>> in the query execution or not (default).|===Do note that most parameters (outside the timeout and `columnar` ones) make sense only during the initial query - any follow-up pagination request only requires the `cursor` parameter as explained in the <<sql-pagination, pagination>> chapter.That's because the query has already been executed and the calls are simply about returning the found results - thus the parameters are simply ignored.
 |