rest.asciidoc 17 KB

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