rest.asciidoc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501
  1. [role="xpack"]
  2. [testenv="basic"]
  3. [[sql-rest]]
  4. == SQL REST API
  5. * <<sql-rest-overview>>
  6. * <<sql-rest-format>>
  7. * <<sql-pagination>>
  8. * <<sql-rest-filtering>>
  9. * <<sql-rest-columnar>>
  10. * <<sql-rest-fields>>
  11. [[sql-rest-overview]]
  12. === Overview
  13. The SQL REST API accepts SQL in a JSON document, executes it,
  14. and returns the results.
  15. For example:
  16. [source,console]
  17. --------------------------------------------------
  18. POST /_sql?format=txt
  19. {
  20. "query": "SELECT * FROM library ORDER BY page_count DESC LIMIT 5"
  21. }
  22. --------------------------------------------------
  23. // TEST[setup:library]
  24. Which returns:
  25. [source,text]
  26. --------------------------------------------------
  27. author | name | page_count | release_date
  28. -----------------+--------------------+---------------+------------------------
  29. Peter F. Hamilton|Pandora's Star |768 |2004-03-02T00:00:00.000Z
  30. Vernor Vinge |A Fire Upon the Deep|613 |1992-06-01T00:00:00.000Z
  31. Frank Herbert |Dune |604 |1965-06-01T00:00:00.000Z
  32. Alastair Reynolds|Revelation Space |585 |2000-03-15T00:00:00.000Z
  33. James S.A. Corey |Leviathan Wakes |561 |2011-06-02T00:00:00.000Z
  34. --------------------------------------------------
  35. // TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]
  36. // TESTRESPONSE[non_json]
  37. [[sql-kibana-console]]
  38. [TIP]
  39. .Using Kibana Console
  40. ====
  41. If you are using {kibana-ref}/console-kibana.html[Kibana Console]
  42. (which is highly recommended), take advantage of the
  43. triple quotes `"""` when creating the query. This not only automatically escapes double
  44. quotes (`"`) inside the query string but also support multi-line as shown below:
  45. image:images/sql/rest/console-triple-quotes.png[]
  46. ====
  47. [[sql-rest-format]]
  48. === Response Data Formats
  49. While the textual format is nice for humans, computers prefer something
  50. more structured.
  51. {es-sql} can return the data in the following formats which can be set
  52. either through the `format` property in the URL or by setting the `Accept` HTTP header:
  53. NOTE: The URL parameter takes precedence over the `Accept` HTTP header.
  54. If neither is specified then the response is returned in the same format as the request.
  55. [cols="^m,^4m,^8"]
  56. |===
  57. s|format
  58. s|`Accept` HTTP header
  59. s|Description
  60. 3+h| Human Readable
  61. |csv
  62. |text/csv
  63. |https://en.wikipedia.org/wiki/Comma-separated_values[Comma-separated values]
  64. |json
  65. |application/json
  66. |https://www.json.org/[JSON] (JavaScript Object Notation) human-readable format
  67. |tsv
  68. |text/tab-separated-values
  69. |https://en.wikipedia.org/wiki/Tab-separated_values[Tab-separated values]
  70. |txt
  71. |text/plain
  72. |CLI-like representation
  73. |yaml
  74. |application/yaml
  75. |https://en.wikipedia.org/wiki/YAML[YAML] (YAML Ain't Markup Language) human-readable format
  76. 3+h| Binary Formats
  77. |cbor
  78. |application/cbor
  79. |http://cbor.io/[Concise Binary Object Representation]
  80. |smile
  81. |application/smile
  82. |https://en.wikipedia.org/wiki/Smile_(data_interchange_format)[Smile] binary data format similar to CBOR
  83. |===
  84. Here are some examples for the human readable formats:
  85. ==== CSV
  86. [source,console]
  87. --------------------------------------------------
  88. POST /_sql?format=csv
  89. {
  90. "query": "SELECT * FROM library ORDER BY page_count DESC",
  91. "fetch_size": 5
  92. }
  93. --------------------------------------------------
  94. // TEST[setup:library]
  95. Which returns:
  96. [source,text]
  97. --------------------------------------------------
  98. author,name,page_count,release_date
  99. Peter F. Hamilton,Pandora's Star,768,2004-03-02T00:00:00.000Z
  100. Vernor Vinge,A Fire Upon the Deep,613,1992-06-01T00:00:00.000Z
  101. Frank Herbert,Dune,604,1965-06-01T00:00:00.000Z
  102. Alastair Reynolds,Revelation Space,585,2000-03-15T00:00:00.000Z
  103. James S.A. Corey,Leviathan Wakes,561,2011-06-02T00:00:00.000Z
  104. --------------------------------------------------
  105. // TESTRESPONSE[non_json]
  106. ==== JSON
  107. [source,console]
  108. --------------------------------------------------
  109. POST /_sql?format=json
  110. {
  111. "query": "SELECT * FROM library ORDER BY page_count DESC",
  112. "fetch_size": 5
  113. }
  114. --------------------------------------------------
  115. // TEST[setup:library]
  116. Which returns:
  117. [source,console-result]
  118. --------------------------------------------------
  119. {
  120. "columns": [
  121. {"name": "author", "type": "text"},
  122. {"name": "name", "type": "text"},
  123. {"name": "page_count", "type": "short"},
  124. {"name": "release_date", "type": "datetime"}
  125. ],
  126. "rows": [
  127. ["Peter F. Hamilton", "Pandora's Star", 768, "2004-03-02T00:00:00.000Z"],
  128. ["Vernor Vinge", "A Fire Upon the Deep", 613, "1992-06-01T00:00:00.000Z"],
  129. ["Frank Herbert", "Dune", 604, "1965-06-01T00:00:00.000Z"],
  130. ["Alastair Reynolds", "Revelation Space", 585, "2000-03-15T00:00:00.000Z"],
  131. ["James S.A. Corey", "Leviathan Wakes", 561, "2011-06-02T00:00:00.000Z"]
  132. ],
  133. "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="
  134. }
  135. --------------------------------------------------
  136. // TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]
  137. ==== TSV
  138. [source,console]
  139. --------------------------------------------------
  140. POST /_sql?format=tsv
  141. {
  142. "query": "SELECT * FROM library ORDER BY page_count DESC",
  143. "fetch_size": 5
  144. }
  145. --------------------------------------------------
  146. // TEST[setup:library]
  147. Which returns:
  148. [source,text]
  149. --------------------------------------------------
  150. author name page_count release_date
  151. Peter F. Hamilton Pandora's Star 768 2004-03-02T00:00:00.000Z
  152. Vernor Vinge A Fire Upon the Deep 613 1992-06-01T00:00:00.000Z
  153. Frank Herbert Dune 604 1965-06-01T00:00:00.000Z
  154. Alastair Reynolds Revelation Space 585 2000-03-15T00:00:00.000Z
  155. James S.A. Corey Leviathan Wakes 561 2011-06-02T00:00:00.000Z
  156. --------------------------------------------------
  157. // TESTRESPONSE[s/\t/ /]
  158. // TESTRESPONSE[non_json]
  159. ==== TXT
  160. [source,console]
  161. --------------------------------------------------
  162. POST /_sql?format=txt
  163. {
  164. "query": "SELECT * FROM library ORDER BY page_count DESC",
  165. "fetch_size": 5
  166. }
  167. --------------------------------------------------
  168. // TEST[setup:library]
  169. Which returns:
  170. [source,text]
  171. --------------------------------------------------
  172. author | name | page_count | release_date
  173. -----------------+--------------------+---------------+------------------------
  174. Peter F. Hamilton|Pandora's Star |768 |2004-03-02T00:00:00.000Z
  175. Vernor Vinge |A Fire Upon the Deep|613 |1992-06-01T00:00:00.000Z
  176. Frank Herbert |Dune |604 |1965-06-01T00:00:00.000Z
  177. Alastair Reynolds|Revelation Space |585 |2000-03-15T00:00:00.000Z
  178. James S.A. Corey |Leviathan Wakes |561 |2011-06-02T00:00:00.000Z
  179. --------------------------------------------------
  180. // TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]
  181. // TESTRESPONSE[non_json]
  182. ==== YAML
  183. [source,console]
  184. --------------------------------------------------
  185. POST /_sql?format=yaml
  186. {
  187. "query": "SELECT * FROM library ORDER BY page_count DESC",
  188. "fetch_size": 5
  189. }
  190. --------------------------------------------------
  191. // TEST[setup:library]
  192. Which returns:
  193. [source,yaml]
  194. --------------------------------------------------
  195. columns:
  196. - name: "author"
  197. type: "text"
  198. - name: "name"
  199. type: "text"
  200. - name: "page_count"
  201. type: "short"
  202. - name: "release_date"
  203. type: "datetime"
  204. rows:
  205. - - "Peter F. Hamilton"
  206. - "Pandora's Star"
  207. - 768
  208. - "2004-03-02T00:00:00.000Z"
  209. - - "Vernor Vinge"
  210. - "A Fire Upon the Deep"
  211. - 613
  212. - "1992-06-01T00:00:00.000Z"
  213. - - "Frank Herbert"
  214. - "Dune"
  215. - 604
  216. - "1965-06-01T00:00:00.000Z"
  217. - - "Alastair Reynolds"
  218. - "Revelation Space"
  219. - 585
  220. - "2000-03-15T00:00:00.000Z"
  221. - - "James S.A. Corey"
  222. - "Leviathan Wakes"
  223. - 561
  224. - "2011-06-02T00:00:00.000Z"
  225. cursor: "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="
  226. --------------------------------------------------
  227. // TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]
  228. [[sql-pagination]]
  229. === Paginating through a large response
  230. Using the example from the <<sql-rest-format,previous section>>, one can
  231. continue to the next page by sending back the cursor field. In case of text
  232. format, the cursor is returned as `Cursor` http header.
  233. [source,console]
  234. --------------------------------------------------
  235. POST /_sql?format=json
  236. {
  237. "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f///w8="
  238. }
  239. --------------------------------------------------
  240. // TEST[continued]
  241. // TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f\/\/\/w8=/$body.cursor/]
  242. Which looks like:
  243. [source,console-result]
  244. --------------------------------------------------
  245. {
  246. "rows" : [
  247. ["Dan Simmons", "Hyperion", 482, "1989-05-26T00:00:00.000Z"],
  248. ["Iain M. Banks", "Consider Phlebas", 471, "1987-04-23T00:00:00.000Z"],
  249. ["Neal Stephenson", "Snow Crash", 470, "1992-06-01T00:00:00.000Z"],
  250. ["Frank Herbert", "God Emperor of Dune", 454, "1981-05-28T00:00:00.000Z"],
  251. ["Frank Herbert", "Children of Dune", 408, "1976-04-21T00:00:00.000Z"]
  252. ],
  253. "cursor" : "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWODRMaXBUaVlRN21iTlRyWHZWYUdrdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl9f///w8="
  254. }
  255. --------------------------------------------------
  256. // TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWODRMaXBUaVlRN21iTlRyWHZWYUdrdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl9f\/\/\/w8=/$body.cursor/]
  257. Note that the `columns` object is only part of the first page.
  258. You've reached the last page when there is no `cursor` returned
  259. in the results. Like Elasticsearch's <<request-body-search-scroll,scroll>>,
  260. SQL may keep state in Elasticsearch to support the cursor. Unlike
  261. scroll, receiving the last page is enough to guarantee that the
  262. Elasticsearch state is cleared.
  263. To clear the state earlier, you can use the clear cursor command:
  264. [source,console]
  265. --------------------------------------------------
  266. POST /_sql/close
  267. {
  268. "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f///w8="
  269. }
  270. --------------------------------------------------
  271. // TEST[continued]
  272. // TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWYUpOYklQMHhRUEtld3RsNnFtYU1hQQ==:BAFmBGRhdGUBZgVsaWtlcwFzB21lc3NhZ2UBZgR1c2Vy9f\/\/\/w8=/$body.cursor/]
  273. Which will like return the
  274. [source,console-result]
  275. --------------------------------------------------
  276. {
  277. "succeeded" : true
  278. }
  279. --------------------------------------------------
  280. [[sql-rest-filtering]]
  281. === Filtering using {es} query DSL
  282. You can filter the results that SQL will run on using a standard
  283. {es} query DSL by specifying the query in the filter
  284. parameter.
  285. [source,console]
  286. --------------------------------------------------
  287. POST /_sql?format=txt
  288. {
  289. "query": "SELECT * FROM library ORDER BY page_count DESC",
  290. "filter": {
  291. "range": {
  292. "page_count": {
  293. "gte" : 100,
  294. "lte" : 200
  295. }
  296. }
  297. },
  298. "fetch_size": 5
  299. }
  300. --------------------------------------------------
  301. // TEST[setup:library]
  302. Which returns:
  303. [source,text]
  304. --------------------------------------------------
  305. author | name | page_count | release_date
  306. ---------------+------------------------------------+---------------+------------------------
  307. Douglas Adams |The Hitchhiker's Guide to the Galaxy|180 |1979-10-12T00:00:00.000Z
  308. --------------------------------------------------
  309. // TESTRESPONSE[s/\|/\\|/ s/\+/\\+/]
  310. // TESTRESPONSE[non_json]
  311. [[sql-rest-columnar]]
  312. === Columnar results
  313. The most well known way of displaying the results of an SQL query result in general is the one where each
  314. individual record/document represents one line/row. For certain formats, {es-sql} can return the results
  315. in a columnar fashion: one row represents all the values of a certain column from the current page of results.
  316. The following formats can be returned in columnar orientation: `json`, `yaml`, `cbor` and `smile`.
  317. [source,console]
  318. --------------------------------------------------
  319. POST /_sql?format=json
  320. {
  321. "query": "SELECT * FROM library ORDER BY page_count DESC",
  322. "fetch_size": 5,
  323. "columnar": true
  324. }
  325. --------------------------------------------------
  326. // TEST[setup:library]
  327. Which returns:
  328. [source,console-result]
  329. --------------------------------------------------
  330. {
  331. "columns": [
  332. {"name": "author", "type": "text"},
  333. {"name": "name", "type": "text"},
  334. {"name": "page_count", "type": "short"},
  335. {"name": "release_date", "type": "datetime"}
  336. ],
  337. "values": [
  338. ["Peter F. Hamilton", "Vernor Vinge", "Frank Herbert", "Alastair Reynolds", "James S.A. Corey"],
  339. ["Pandora's Star", "A Fire Upon the Deep", "Dune", "Revelation Space", "Leviathan Wakes"],
  340. [768, 613, 604, 585, 561],
  341. ["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"]
  342. ],
  343. "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8="
  344. }
  345. --------------------------------------------------
  346. // TESTRESPONSE[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]
  347. Any subsequent calls using a `cursor` still have to contain the `columnar` parameter to preserve the orientation,
  348. meaning the initial query will not _remember_ the columnar option.
  349. [source,console]
  350. --------------------------------------------------
  351. POST /_sql?format=json
  352. {
  353. "cursor": "sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl+v///w8=",
  354. "columnar": true
  355. }
  356. --------------------------------------------------
  357. // TEST[continued]
  358. // TEST[s/sDXF1ZXJ5QW5kRmV0Y2gBAAAAAAAAAAEWWWdrRlVfSS1TbDYtcW9lc1FJNmlYdw==:BAFmBmF1dGhvcgFmBG5hbWUBZgpwYWdlX2NvdW50AWYMcmVsZWFzZV9kYXRl\+v\/\/\/w8=/$body.cursor/]
  359. Which looks like:
  360. [source,console-result]
  361. --------------------------------------------------
  362. {
  363. "values": [
  364. ["Dan Simmons", "Iain M. Banks", "Neal Stephenson", "Frank Herbert", "Frank Herbert"],
  365. ["Hyperion", "Consider Phlebas", "Snow Crash", "God Emperor of Dune", "Children of Dune"],
  366. [482, 471, 470, 454, 408],
  367. ["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"]
  368. ],
  369. "cursor": "46ToAwFzQERYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQUVXWjBaNlFXbzNOV0pVY21Wa1NUZDJhV2t3V2xwblp3PT3/////DwQBZgZhdXRob3IBBHRleHQAAAFmBG5hbWUBBHRleHQAAAFmCnBhZ2VfY291bnQBBGxvbmcBAAFmDHJlbGVhc2VfZGF0ZQEIZGF0ZXRpbWUBAAEP"
  370. }
  371. --------------------------------------------------
  372. // TESTRESPONSE[s/46ToAwFzQERYRjFaWEo1UVc1a1JtVjBZMmdCQUFBQUFBQUFBQUVXWjBaNlFXbzNOV0pVY21Wa1NUZDJhV2t3V2xwblp3PT3\/\/\/\/\/DwQBZgZhdXRob3IBBHRleHQAAAFmBG5hbWUBBHRleHQAAAFmCnBhZ2VfY291bnQBBGxvbmcBAAFmDHJlbGVhc2VfZGF0ZQEIZGF0ZXRpbWUBAAEP/$body.cursor/]
  373. [[sql-rest-fields]]
  374. === Supported REST parameters
  375. In addition to the `query` and `fetch_size`, a request a number of user-defined fields for specifying
  376. the request time-outs or localization information (such as timezone).
  377. The table below lists the supported parameters:
  378. [cols="^m,^m,^5"]
  379. |===
  380. s|name
  381. s|Default value
  382. s|Description
  383. |query
  384. |Mandatory
  385. |SQL query to execute
  386. |fetch_size
  387. |1000
  388. |The maximum number of rows (or entries) to return in one response
  389. |filter
  390. |none
  391. |Optional {es} query DSL for additional <<sql-rest-filtering, filtering>>.
  392. |request_timeout
  393. |90s
  394. |The timeout before the request fails.
  395. |page_timeout
  396. |45s
  397. |The timeout before a pagination request fails.
  398. |time_zone
  399. |`Z` (or `UTC`)
  400. |Time-zone in ISO 8601 used for executing the query on the server.
  401. More information available https://docs.oracle.com/javase/8/docs/api/java/time/ZoneId.html[here].
  402. |columnar
  403. |false
  404. |Return the results in a columnar fashion, rather than row-based fashion. Valid for `json`, `yaml`, `cbor` and `smile`.
  405. |field_multi_value_leniency
  406. |false
  407. |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).
  408. |index_include_frozen
  409. |false
  410. |Whether to include <<frozen-indices, frozen-indices>> in the query execution or not (default).
  411. |===
  412. 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.
  413. 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.