rest.asciidoc 17 KB

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