ES|QL REST API

概要

ES|QLクエリAPIは、queryパラメータにES|QLクエリ文字列を受け入れ、それを実行して結果を返します。例えば:

Python

  1. resp = client.esql.query(
  2. format="txt",
  3. query="FROM library | KEEP author, name, page_count, release_date | SORT page_count DESC | LIMIT 5",
  4. )
  5. print(resp)

Js

  1. const response = await client.esql.query({
  2. format: "txt",
  3. query:
  4. "FROM library | KEEP author, name, page_count, release_date | SORT page_count DESC | LIMIT 5",
  5. });
  6. console.log(response);

コンソール

  1. POST /_query?format=txt
  2. {
  3. "query": "FROM library | KEEP author, name, page_count, release_date | SORT page_count DESC | LIMIT 5"
  4. }

返されるのは:

テキスト

  1. author | name | page_count | release_date
  2. -----------------+--------------------+---------------+------------------------
  3. Peter F. Hamilton|Pandora's Star |768 |2004-03-02T00:00:00.000Z
  4. Vernor Vinge |A Fire Upon the Deep|613 |1992-06-01T00:00:00.000Z
  5. Frank Herbert |Dune |604 |1965-06-01T00:00:00.000Z
  6. Alastair Reynolds|Revelation Space |585 |2000-03-15T00:00:00.000Z
  7. James S.A. Corey |Leviathan Wakes |561 |2011-06-02T00:00:00.000Z

Kibanaコンソール

Kibana Consoleを使用している場合(強く推奨されます)、クエリを作成する際に三重引用符"""を活用してください。これにより、クエリ文字列内の二重引用符(")が自動的にエスケープされるだけでなく、複数行のリクエストもサポートされます:

Python

  1. resp = client.esql.query(
  2. format="txt",
  3. query="\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  4. )
  5. print(resp)

Js

  1. const response = await client.esql.query({
  2. format: "txt",
  3. query:
  4. "\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  5. });
  6. console.log(response);

コンソール

  1. POST /_query?format=txt
  2. {
  3. "query": """
  4. FROM library
  5. | KEEP author, name, page_count, release_date
  6. | SORT page_count DESC
  7. | LIMIT 5
  8. """
  9. }

レスポンスフォーマット

ES|QLは、以下の人間が読みやすい形式とバイナリ形式でデータを返すことができます。フォーマットは、URL内のformatパラメータを指定するか、AcceptまたはContent-TypeHTTPヘッダーを設定することで指定できます。

URLパラメータはHTTPヘッダーよりも優先されます。どちらも指定されていない場合、レスポンスはリクエストと同じフォーマットで返されます。


| | | |
| —- | —- | —- |
| format | HTTPヘッダー | 説明 |
| 人間が読みやすい |
| csv | text/csv | カンマ区切り値 |
| json | application/json | JSON(JavaScriptオブジェクト表記)人間が読みやすい形式 |
| tsv | text/tab-separated-values | タブ区切り値 |
| txt | text/plain | CLIのような表現 |
| yaml | application/yaml | YAML(YAMLはマークアップ言語ではない)人間が読みやすい形式 |
| バイナリ |
| cbor | application/cbor | 簡潔なバイナリオブジェクト表現 |
| smile | application/smile | Smile)CBORに似たバイナリデータ形式 |
| arrow | application/vnd.apache.arrow.stream | 実験的。 Apache Arrowデータフレーム、IPCストリーミング形式 |

  1. ### Elasticsearch Query DSLを使用したフィルタリング
  2. `````filter`````パラメータにQuery DSLクエリを指定して、ES|QLクエリが実行されるドキュメントのセットをフィルタリングします。
  3. #### Python
  4. ``````python
  5. resp = client.esql.query(
  6. format="txt",
  7. query="\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  8. filter={
  9. "range": {
  10. "page_count": {
  11. "gte": 100,
  12. "lte": 200
  13. }
  14. }
  15. },
  16. )
  17. print(resp)
  18. `

Js

  1. const response = await client.esql.query({
  2. format: "txt",
  3. query:
  4. "\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  5. filter: {
  6. range: {
  7. page_count: {
  8. gte: 100,
  9. lte: 200,
  10. },
  11. },
  12. },
  13. });
  14. console.log(response);

コンソール

  1. POST /_query?format=txt
  2. {
  3. "query": """
  4. FROM library
  5. | KEEP author, name, page_count, release_date
  6. | SORT page_count DESC
  7. | LIMIT 5
  8. """,
  9. "filter": {
  10. "range": {
  11. "page_count": {
  12. "gte": 100,
  13. "lte": 200
  14. }
  15. }
  16. }
  17. }

返されるのは:

テキスト

  1. author | name | page_count | release_date
  2. ---------------+------------------------------------+---------------+------------------------
  3. Douglas Adams |The Hitchhiker's Guide to the Galaxy|180 |1979-10-12T00:00:00.000Z

列形式の結果

デフォルトでは、ES|QLは結果を行として返します。例えば、FROMは各個別のドキュメントを1行として返します。jsonyamlcborおよびsmile フォーマットに対して、ES|QLは結果を列形式で返すことができ、1行が結果の特定の列のすべての値を表します。

Python

  1. resp = client.esql.query(
  2. format="json",
  3. query="\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  4. columnar=True,
  5. )
  6. print(resp)

Js

  1. const response = await client.esql.query({
  2. format: "json",
  3. query:
  4. "\n FROM library\n | KEEP author, name, page_count, release_date\n | SORT page_count DESC\n | LIMIT 5\n ",
  5. columnar: true,
  6. });
  7. console.log(response);

コンソール

  1. POST /_query?format=json
  2. {
  3. "query": """
  4. FROM library
  5. | KEEP author, name, page_count, release_date
  6. | SORT page_count DESC
  7. | LIMIT 5
  8. """,
  9. "columnar": true
  10. }

返されるのは:

コンソール-結果

  1. {
  2. "columns": [
  3. {"name": "author", "type": "text"},
  4. {"name": "name", "type": "text"},
  5. {"name": "page_count", "type": "integer"},
  6. {"name": "release_date", "type": "date"}
  7. ],
  8. "values": [
  9. ["Peter F. Hamilton", "Vernor Vinge", "Frank Herbert", "Alastair Reynolds", "James S.A. Corey"],
  10. ["Pandora's Star", "A Fire Upon the Deep", "Dune", "Revelation Space", "Leviathan Wakes"],
  11. [768, 613, 604, 585, 561],
  12. ["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"]
  13. ]
  14. }

ローカライズされた結果の返却

リクエストボディ内のlocaleパラメータを使用して、ロケールの規則に従ってフォーマットされた結果(特に日付)を返します。localeが指定されていない場合、デフォルトはen-US(英語)です。JDKサポートロケールを参照してください。

構文:localeパラメータは、(大文字と小文字を区別しない)形式xyおよびxy-XYの言語タグを受け入れます。

例えば、フランス語で月の名前を返すには:

Python

  1. resp = client.esql.query(
  2. locale="fr-FR",
  3. query="\n ROW birth_date_string = \"2023-01-15T00:00:00.000Z\"\n | EVAL birth_date = date_parse(birth_date_string)\n | EVAL month_of_birth = DATE_FORMAT(\"MMMM\",birth_date)\n | LIMIT 5\n ",
  4. )
  5. print(resp)

Js

  1. const response = await client.esql.query({
  2. locale: "fr-FR",
  3. query:
  4. '\n ROW birth_date_string = "2023-01-15T00:00:00.000Z"\n | EVAL birth_date = date_parse(birth_date_string)\n | EVAL month_of_birth = DATE_FORMAT("MMMM",birth_date)\n | LIMIT 5\n ',
  5. });
  6. console.log(response);

コンソール

  1. POST /_query
  2. {
  3. "locale": "fr-FR",
  4. "query": """
  5. ROW birth_date_string = "2023-01-15T00:00:00.000Z"
  6. | EVAL birth_date = date_parse(birth_date_string)
  7. | EVAL month_of_birth = DATE_FORMAT("MMMM",birth_date)
  8. | LIMIT 5
  9. """
  10. }

クエリへのパラメータの渡し方

条件のための値は、クエリ文字列自体に値を統合することによって「インライン」でクエリに渡すことができます:

Python

  1. resp = client.esql.query(
  2. query="\n FROM library\n | EVAL year = DATE_EXTRACT(\"year\", release_date)\n | WHERE page_count > 300 AND author == \"Frank Herbert\"\n | STATS count = COUNT(*) by year\n | WHERE count > 0\n | LIMIT 5\n ",
  3. )
  4. print(resp)

Js

  1. const response = await client.esql.query({
  2. query:
  3. '\n FROM library\n | EVAL year = DATE_EXTRACT("year", release_date)\n | WHERE page_count > 300 AND author == "Frank Herbert"\n | STATS count = COUNT(*) by year\n | WHERE count > 0\n | LIMIT 5\n ',
  4. });
  5. console.log(response);

コンソール

  1. POST /_query
  2. {
  3. "query": """
  4. FROM library
  5. | EVAL year = DATE_EXTRACT("year", release_date)
  6. | WHERE page_count > 300 AND author == "Frank Herbert"
  7. | STATS count = COUNT(*) by year
  8. | WHERE count > 0
  9. | LIMIT 5
  10. """
  11. }

ハッキングやコードインジェクションの試みを避けるために、値を別のパラメータリストに抽出します。クエリ文字列内の各パラメータに対して、疑問符プレースホルダー(?)を使用します:

Python

  1. resp = client.esql.query(
  2. query="\n FROM library\n | EVAL year = DATE_EXTRACT(\"year\", release_date)\n | WHERE page_count > ? AND author == ?\n | STATS count = COUNT(*) by year\n | WHERE count > ?\n | LIMIT 5\n ",
  3. params=[
  4. 300,
  5. "Frank Herbert",
  6. 0
  7. ],
  8. )
  9. print(resp)

Js

  1. const response = await client.esql.query({
  2. query:
  3. '\n FROM library\n | EVAL year = DATE_EXTRACT("year", release_date)\n | WHERE page_count > ? AND author == ?\n | STATS count = COUNT(*) by year\n | WHERE count > ?\n | LIMIT 5\n ',
  4. params: [300, "Frank Herbert", 0],
  5. });
  6. console.log(response);

コンソール

  1. POST /_query
  2. {
  3. "query": """
  4. FROM library
  5. | EVAL year = DATE_EXTRACT("year", release_date)
  6. | WHERE page_count > ? AND author == ?
  7. | STATS count = COUNT(*) by year
  8. | WHERE count > ?
  9. | LIMIT 5
  10. """,
  11. "params": [300, "Frank Herbert", 0]
  12. }

パラメータは、名前付きパラメータまたは位置パラメータである可能性があります。

名前付きパラメータは、文字列の後に疑問符プレースホルダー(?)を使用します。

Python

  1. resp = client.esql.query(
  2. query="\n FROM library\n | EVAL year = DATE_EXTRACT(\"year\", release_date)\n | WHERE page_count > ?page_count AND author == ?author\n | STATS count = COUNT(*) by year\n | WHERE count > ?count\n | LIMIT 5\n ",
  3. params=[
  4. {
  5. "page_count": 300
  6. },
  7. {
  8. "author": "Frank Herbert"
  9. },
  10. {
  11. "count": 0
  12. }
  13. ],
  14. )
  15. print(resp)

Js

  1. const response = await client.esql.query({
  2. query:
  3. '\n FROM library\n | EVAL year = DATE_EXTRACT("year", release_date)\n | WHERE page_count > ?page_count AND author == ?author\n | STATS count = COUNT(*) by year\n | WHERE count > ?count\n | LIMIT 5\n ',
  4. params: [
  5. {
  6. page_count: 300,
  7. },
  8. {
  9. author: "Frank Herbert",
  10. },
  11. {
  12. count: 0,
  13. },
  14. ],
  15. });
  16. console.log(response);

コンソール

  1. POST /_query
  2. {
  3. "query": """
  4. FROM library
  5. | EVAL year = DATE_EXTRACT("year", release_date)
  6. | WHERE page_count > ?page_count AND author == ?author
  7. | STATS count = COUNT(*) by year
  8. | WHERE count > ?count
  9. | LIMIT 5
  10. """,
  11. "params": [{"page_count" : 300}, {"author" : "Frank Herbert"}, {"count" : 0}]
  12. }

位置パラメータは、整数の後に疑問符プレースホルダー(?)を使用します。

Python

  1. resp = client.esql.query(
  2. query="\n FROM library\n | EVAL year = DATE_EXTRACT(\"year\", release_date)\n | WHERE page_count > ?1 AND author == ?2\n | STATS count = COUNT(*) by year\n | WHERE count > ?3\n | LIMIT 5\n ",
  3. params=[
  4. 300,
  5. "Frank Herbert",
  6. 0
  7. ],
  8. )
  9. print(resp)

Js

  1. const response = await client.esql.query({
  2. query:
  3. '\n FROM library\n | EVAL year = DATE_EXTRACT("year", release_date)\n | WHERE page_count > ?1 AND author == ?2\n | STATS count = COUNT(*) by year\n | WHERE count > ?3\n | LIMIT 5\n ',
  4. params: [300, "Frank Herbert", 0],
  5. });
  6. console.log(response);

コンソール

  1. POST /_query
  2. {
  3. "query": """
  4. FROM library
  5. | EVAL year = DATE_EXTRACT("year", release_date)
  6. | WHERE page_count > ?1 AND author == ?2
  7. | STATS count = COUNT(*) by year
  8. | WHERE count > ?3
  9. | LIMIT 5
  10. """,
  11. "params": [300, "Frank Herbert", 0]
  12. }

非同期ES|QLクエリの実行

ES|QL非同期クエリAPIを使用すると、クエリリクエストを非同期に実行し、その進行状況を監視し、結果が利用可能になったときに取得できます。

ES|QLクエリの実行は通常非常に速いですが、大規模なデータセットや凍結データに対するクエリは時間がかかることがあります。長時間の待機を避けるために、非同期ES|QLクエリを実行します。

非同期クエリAPIによって開始されたクエリは、結果を返す場合と返さない場合があります。wait_for_completion_timeoutプロパティは、結果を待つ時間を決定します。この時間内に結果が利用できない場合、クエリIDが返され、後で結果を取得するために使用できます。例えば:

Python

  1. resp = client.esql.async_query(
  2. body={
  3. "query": "\n FROM library\n | EVAL year = DATE_TRUNC(1 YEARS, release_date)\n | STATS MAX(page_count) BY year\n | SORT year\n | LIMIT 5\n ",
  4. "wait_for_completion_timeout": "2s"
  5. },
  6. )
  7. print(resp)

Js

  1. const response = await client.esql.asyncQuery({
  2. body: {
  3. query:
  4. "\n FROM library\n | EVAL year = DATE_TRUNC(1 YEARS, release_date)\n | STATS MAX(page_count) BY year\n | SORT year\n | LIMIT 5\n ",
  5. wait_for_completion_timeout: "2s",
  6. },
  7. });
  8. console.log(response);

コンソール

  1. POST /_query/async
  2. {
  3. "query": """
  4. FROM library
  5. | EVAL year = DATE_TRUNC(1 YEARS, release_date)
  6. | STATS MAX(page_count) BY year
  7. | SORT year
  8. | LIMIT 5
  9. """,
  10. "wait_for_completion_timeout": "2s"
  11. }

指定されたタイムアウト期間内に結果が利用できない場合、この場合は2秒、結果は返されず、次の内容を含むレスポンスが返されます:

  • クエリID
  • クエリが進行中であることを示すis_running値がtrue

クエリは、他のリクエストをブロックすることなくバックグラウンドで実行され続けます。

コンソール-結果

  1. {
  2. "id": "FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=",
  3. "is_running": true
  4. }

非同期クエリの進行状況を確認するには、クエリIDを使用してES|QL非同期クエリ取得APIを使用します。完全な結果を待つ時間をwait_for_completion_timeoutパラメータで指定します。

Python

  1. resp = client.esql.async_query_get(
  2. id="FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=",
  3. wait_for_completion_timeout="30s",
  4. body=None,
  5. )
  6. print(resp)

Ruby

  1. response = client.esql.async_query_get(
  2. id: 'FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=',
  3. wait_for_completion_timeout: '30s'
  4. )
  5. puts response

Js

  1. const response = await client.esql.asyncQueryGet({
  2. id: "FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=",
  3. wait_for_completion_timeout: "30s",
  4. body: null,
  5. });
  6. console.log(response);

コンソール

  1. GET /_query/async/FmNJRUZ1YWZCU3dHY1BIOUhaenVSRkEaaXFlZ3h4c1RTWFNocDdnY2FSaERnUTozNDE=?wait_for_completion_timeout=30s

レスポンスのis_running値がfalseである場合、クエリは完了し、結果が返されます。

コンソール-結果

  1. {
  2. "is_running": false,
  3. "columns": ...
  4. }
  1. [](#67b71a95b6fe6c83faae51ea038a1bf1)
  2. #### コンソール
  3. ``````console
  4. DELETE /_query/async/FmdMX2pIang3UWhLRU5QS0lqdlppYncaMUpYQ05oSkpTc3kwZ21EdC1tbFJXQToxOTI=
  5. `