esql-rest.asciidoc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  1. [[esql-rest]]
  2. === {esql} REST API
  3. ++++
  4. <titleabbrev>REST API</titleabbrev>
  5. ++++
  6. [discrete]
  7. [[esql-rest-overview]]
  8. === Overview
  9. The <<esql-query-api,{esql} query API>> accepts an {esql} query string in the
  10. `query` parameter, runs it, and returns the results. For example:
  11. [source,console]
  12. ----
  13. POST /_query?format=txt
  14. {
  15. "query": "FROM library | KEEP author, name, page_count, release_date | SORT page_count DESC | LIMIT 5"
  16. }
  17. ----
  18. // TEST[setup:library]
  19. Which returns:
  20. [source,text]
  21. ----
  22. author | name | page_count | release_date
  23. -----------------+--------------------+---------------+------------------------
  24. Peter F. Hamilton|Pandora's Star |768 |2004-03-02T00:00:00.000Z
  25. Vernor Vinge |A Fire Upon the Deep|613 |1992-06-01T00:00:00.000Z
  26. Frank Herbert |Dune |604 |1965-06-01T00:00:00.000Z
  27. Alastair Reynolds|Revelation Space |585 |2000-03-15T00:00:00.000Z
  28. James S.A. Corey |Leviathan Wakes |561 |2011-06-02T00:00:00.000Z
  29. ----
  30. // TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]
  31. // TESTRESPONSE[non_json]
  32. [discrete]
  33. [[esql-kibana-console]]
  34. ==== Run the {esql} query API in Console
  35. We recommend using {kibana-ref}/console-kibana.html[Console] to run the {esql}
  36. query API. When creating the query, using triple quotes (`"""`) allows you to
  37. use special characters like quotes (`"`) without having to escape them. They
  38. also make it easier to write multi-line requests:
  39. // tag::esql-query-api[]
  40. [source,console]
  41. ----
  42. POST /_query?format=txt
  43. {
  44. "query": """
  45. FROM library
  46. | KEEP author, name, page_count, release_date
  47. | SORT page_count DESC
  48. | LIMIT 5
  49. """
  50. }
  51. ----
  52. // TEST[setup:library]
  53. Inside quotes, Console suggests possible commands and functions to autocomplete your query:
  54. image::images/esql/console-esql-autocomplete.png[align="center"]
  55. [discrete]
  56. [[esql-rest-format]]
  57. ==== Response formats
  58. {esql} can return the data in the following human readable and binary formats.
  59. You can set the format by specifying the `format` parameter in the URL or by
  60. setting the `Accept` or `Content-Type` HTTP header.
  61. NOTE: The URL parameter takes precedence over the HTTP headers. If neither is
  62. specified then the response is returned in the same format as the request.
  63. [cols="m,4m,8"]
  64. |===
  65. s|`format`
  66. s|HTTP header
  67. s|Description
  68. 3+h| Human readable
  69. |csv
  70. |text/csv
  71. |{wikipedia}/Comma-separated_values[Comma-separated values]
  72. |json
  73. |application/json
  74. |https://www.json.org/[JSON] (JavaScript Object Notation) human-readable format
  75. |tsv
  76. |text/tab-separated-values
  77. |{wikipedia}/Tab-separated_values[Tab-separated values]
  78. |txt
  79. |text/plain
  80. |CLI-like representation
  81. |yaml
  82. |application/yaml
  83. |{wikipedia}/YAML[YAML] (YAML Ain't Markup Language) human-readable format
  84. 3+h| Binary
  85. |cbor
  86. |application/cbor
  87. |https://cbor.io/[Concise Binary Object Representation]
  88. |smile
  89. |application/smile
  90. |{wikipedia}/Smile_(data_interchange_format)[Smile] binary data format similar
  91. to CBOR
  92. |arrow
  93. |application/vnd.apache.arrow.stream
  94. |**Experimental.** https://arrow.apache.org/[Apache Arrow] dataframes, https://arrow.apache.org/docs/format/Columnar.html#ipc-streaming-format[IPC streaming format]
  95. |===
  96. The `csv` format accepts a formatting URL query attribute, `delimiter`, which
  97. indicates which character should be used to separate the CSV values. It defaults
  98. to comma (`,`) and cannot take any of the following values: double quote (`"`),
  99. carriage-return (`\r`) and new-line (`\n`). The tab (`\t`) can also not be used.
  100. Use the `tsv` format instead.
  101. [discrete]
  102. [[esql-rest-filtering]]
  103. ==== Filtering using {es} Query DSL
  104. Specify a Query DSL query in the `filter` parameter to filter the set of
  105. documents that an {esql} query runs on.
  106. [source,console]
  107. ----
  108. POST /_query?format=txt
  109. {
  110. "query": """
  111. FROM library
  112. | KEEP author, name, page_count, release_date
  113. | SORT page_count DESC
  114. | LIMIT 5
  115. """,
  116. "filter": {
  117. "range": {
  118. "page_count": {
  119. "gte": 100,
  120. "lte": 200
  121. }
  122. }
  123. }
  124. }
  125. ----
  126. // TEST[setup:library]
  127. Which returns:
  128. [source,text]
  129. --------------------------------------------------
  130. author | name | page_count | release_date
  131. ---------------+------------------------------------+---------------+------------------------
  132. Douglas Adams |The Hitchhiker's Guide to the Galaxy|180 |1979-10-12T00:00:00.000Z
  133. --------------------------------------------------
  134. // TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]
  135. // TESTRESPONSE[non_json]
  136. [discrete]
  137. [[esql-rest-columnar]]
  138. ==== Columnar results
  139. By default, {esql} returns results as rows. For example, `FROM` returns each
  140. individual document as one row. For the `json`, `yaml`, `cbor` and `smile`
  141. <<esql-rest-format,formats>>, {esql} can return the results in a columnar
  142. fashion where one row represents all the values of a certain column in the
  143. results.
  144. [source,console]
  145. ----
  146. POST /_query?format=json
  147. {
  148. "query": """
  149. FROM library
  150. | KEEP author, name, page_count, release_date
  151. | SORT page_count DESC
  152. | LIMIT 5
  153. """,
  154. "columnar": true
  155. }
  156. ----
  157. // TEST[setup:library]
  158. Which returns:
  159. [source,console-result]
  160. ----
  161. {
  162. "took": 28,
  163. "is_partial": false,
  164. "documents_found": 5,
  165. "values_loaded": 20,
  166. "columns": [
  167. {"name": "author", "type": "text"},
  168. {"name": "name", "type": "text"},
  169. {"name": "page_count", "type": "integer"},
  170. {"name": "release_date", "type": "date"}
  171. ],
  172. "values": [
  173. ["Peter F. Hamilton", "Vernor Vinge", "Frank Herbert", "Alastair Reynolds", "James S.A. Corey"],
  174. ["Pandora's Star", "A Fire Upon the Deep", "Dune", "Revelation Space", "Leviathan Wakes"],
  175. [768, 613, 604, 585, 561],
  176. ["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"]
  177. ]
  178. }
  179. ----
  180. // TESTRESPONSE[s/"took": 28/"took": "$body.took"/]
  181. [discrete]
  182. [[esql-locale-param]]
  183. ==== Returning localized results
  184. Use the `locale` parameter in the request body to return results (especially dates) formatted per the conventions of the locale.
  185. If `locale` is not specified, defaults to `en-US` (English).
  186. Refer to https://www.oracle.com/java/technologies/javase/jdk17-suported-locales.html[JDK Supported Locales].
  187. Syntax: the `locale` parameter accepts language tags in the (case-insensitive) format `xy` and `xy-XY`.
  188. For example, to return a month name in French:
  189. [source,console]
  190. ----
  191. POST /_query
  192. {
  193. "locale": "fr-FR",
  194. "query": """
  195. ROW birth_date_string = "2023-01-15T00:00:00.000Z"
  196. | EVAL birth_date = date_parse(birth_date_string)
  197. | EVAL month_of_birth = DATE_FORMAT("MMMM",birth_date)
  198. | LIMIT 5
  199. """
  200. }
  201. ----
  202. // TEST[setup:library]
  203. // TEST[skip:This can output a warning, and asciidoc doesn't support allowed_warnings]
  204. [discrete]
  205. [[esql-rest-params]]
  206. ==== Passing parameters to a query
  207. Values, for example for a condition, can be passed to a query "inline", by
  208. integrating the value in the query string itself:
  209. [source,console]
  210. ----
  211. POST /_query
  212. {
  213. "query": """
  214. FROM library
  215. | EVAL year = DATE_EXTRACT("year", release_date)
  216. | WHERE page_count > 300 AND author == "Frank Herbert"
  217. | STATS count = COUNT(*) by year
  218. | WHERE count > 0
  219. | LIMIT 5
  220. """
  221. }
  222. ----
  223. // TEST[setup:library]
  224. To avoid any attempts of hacking or code injection, extract the values in a
  225. separate list of parameters. Use question mark placeholders (`?`) in the query
  226. string for each of the parameters:
  227. [source,console]
  228. ----
  229. POST /_query
  230. {
  231. "query": """
  232. FROM library
  233. | EVAL year = DATE_EXTRACT("year", release_date)
  234. | WHERE page_count > ? AND author == ?
  235. | STATS count = COUNT(*) by year
  236. | WHERE count > ?
  237. | LIMIT 5
  238. """,
  239. "params": [300, "Frank Herbert", 0]
  240. }
  241. ----
  242. // TEST[setup:library]
  243. The parameters can be named parameters or positional parameters.
  244. Named parameters use question mark placeholders (`?`) followed by a string.
  245. [source,console]
  246. ----
  247. POST /_query
  248. {
  249. "query": """
  250. FROM library
  251. | EVAL year = DATE_EXTRACT("year", release_date)
  252. | WHERE page_count > ?page_count AND author == ?author
  253. | STATS count = COUNT(*) by year
  254. | WHERE count > ?count
  255. | LIMIT 5
  256. """,
  257. "params": [{"page_count" : 300}, {"author" : "Frank Herbert"}, {"count" : 0}]
  258. }
  259. ----
  260. // TEST[setup:library]
  261. Positional parameters use question mark placeholders (`?`) followed by an
  262. integer.
  263. [source,console]
  264. ----
  265. POST /_query
  266. {
  267. "query": """
  268. FROM library
  269. | EVAL year = DATE_EXTRACT("year", release_date)
  270. | WHERE page_count > ?1 AND author == ?2
  271. | STATS count = COUNT(*) by year
  272. | WHERE count > ?3
  273. | LIMIT 5
  274. """,
  275. "params": [300, "Frank Herbert", 0]
  276. }
  277. ----
  278. // TEST[setup:library]
  279. [discrete]
  280. [[esql-rest-async-query]]
  281. ==== Running an async {esql} query
  282. The <<esql-async-query-api,{esql} async query API>> lets you asynchronously
  283. execute a query request, monitor its progress, and retrieve results when
  284. they become available.
  285. Executing an {esql} query is commonly quite fast, however queries across
  286. large data sets or frozen data can take some time. To avoid long waits,
  287. run an async {esql} query.
  288. Queries initiated by the async query API may return results or not. The
  289. `wait_for_completion_timeout` property determines how long to wait for
  290. the results. If the results are not available by this time, a
  291. <<esql-async-query-api-response-body-query-id,query id>> is returned which
  292. can be later used to retrieve the results. For example:
  293. [source,console]
  294. ----
  295. POST /_query/async
  296. {
  297. "query": """
  298. FROM library
  299. | EVAL year = DATE_TRUNC(1 YEARS, release_date)
  300. | STATS MAX(page_count) BY year
  301. | SORT year
  302. | LIMIT 5
  303. """,
  304. "wait_for_completion_timeout": "2s"
  305. }
  306. ----
  307. // TEST[setup:library]
  308. // TEST[skip:awaitsfix https://github.com/elastic/elasticsearch/issues/104013]
  309. If the results are not available within the given timeout period, 2
  310. seconds in this case, no results are returned but rather a response that
  311. includes:
  312. * A query ID
  313. * An `is_running` value of _true_, indicating the query is ongoing
  314. The query continues to run in the background without blocking other
  315. requests.
  316. [source,console-result]
  317. ----
  318. {
  319. "id": "FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=",
  320. "is_running": true
  321. }
  322. ----
  323. // TEST[skip: no access to query ID - may return response values]
  324. To check the progress of an async query, use the <<esql-async-query-get-api,
  325. {esql} async query get API>> with the query ID. Specify how long you'd like
  326. to wait for complete results in the `wait_for_completion_timeout` parameter.
  327. [source,console]
  328. ----
  329. GET /_query/async/FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=?wait_for_completion_timeout=30s
  330. ----
  331. // TEST[skip: no access to query ID - may return response values]
  332. If the response's `is_running` value is `false`, the query has finished
  333. and the results are returned, along with the `took` time for the query.
  334. [source,console-result]
  335. ----
  336. {
  337. "is_running": false,
  338. "took": 48,
  339. "columns": ...
  340. }
  341. ----
  342. // TEST[skip: no access to query ID - may return response values]
  343. Use the <<esql-async-query-delete-api, {esql} async query delete API>> to
  344. delete an async query before the `keep_alive` period ends. If the query
  345. is still running, {es} cancels it.
  346. [source,console]
  347. ----
  348. DELETE /_query/async/FmdMX2pIang3UWhLRU5QS0lqdlppYncaMUpYQ05oSkpTc3kwZ21EdC1tbFJXQToxOTI=
  349. ----
  350. // TEST[skip: no access to query ID]