SQLの制限

大きなクエリはParsingExceptionをスローする可能性があります

非常に大きなクエリは、解析フェーズ中にメモリを過剰に消費する可能性があり、その場合、Elasticsearch SQLエンジンは解析を中止し、エラーをスローします。そのような場合は、クエリを簡略化したり、小さなクエリに分割したりして、サイズを小さくすることを検討してください。

SYS COLUMNSおよびDESCRIBE TABLEのネストされたフィールド

Elasticsearchには、nestedフィールドと呼ばれる特別なタイプのリレーションシップフィールドがあります。Elasticsearch SQLでは、内部のサブフィールドを参照することで使用できます。SYS COLUMNSがドライバーモードでない場合(CLIおよびREST呼び出しで)およびDESCRIBE TABLEは、NESTED型として表示されますが、クエリで使用することはできません。サブフィールドは次の形式でのみ参照できます:

Sql

  1. [nested_field_name].[sub_field_name]

例えば:

Sql

  1. SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages;

WHEREおよびORDER BY句でのネストされたフィールドに対するスカラー関数の使用は許可されていません

Elasticsearch SQLは、WHEREおよびORDER BY句のネストされたフィールドに対するスカラー関数の使用をサポートしていません。比較演算子および論理演算子を除きます。

例えば:

Sql

  1. SELECT * FROM test_emp WHERE LENGTH(dep.dep_name.keyword) > 5;

そして

Sql

  1. SELECT * FROM test_emp ORDER BY YEAR(dep.start_date);

はサポートされていませんが:

Sql

  1. SELECT * FROM test_emp WHERE dep.start_date >= CAST('2020-01-01' AS DATE) OR dep.dep_end_date IS NULL;

はサポートされています。

マルチネストされたフィールド

Elasticsearch SQLはマルチネストされたドキュメントをサポートしていないため、クエリはインデックス内の1つのネストされたフィールドを参照することができません。これはマルチレベルのネストされたフィールドにも適用されますが、同じレベルで定義された複数のネストされたフィールドにも適用されます。例えば、このインデックスの場合:

Sql

  1. column | type | mapping
  2. ----------------------+---------------+-------------
  3. nested_A |STRUCT |NESTED
  4. nested_A.nested_X |STRUCT |NESTED
  5. nested_A.nested_X.text|VARCHAR |KEYWORD
  6. nested_A.text |VARCHAR |KEYWORD
  7. nested_B |STRUCT |NESTED
  8. nested_B.text |VARCHAR |KEYWORD

nested_Anested_Bは同時に使用できず、nested_A/nested_Bnested_A.nested_Xの組み合わせも使用できません。そのような状況では、Elasticsearch SQLはエラーメッセージを表示します。

ネストされた内部ヒットのページネーション

ネストされたフィールドをSELECTする際、ページネーションは期待通りに機能しません。Elasticsearch SQLは少なくともページサイズのレコードを返します。これは、Elasticsearchにおけるネストされたクエリの動作によるものです:ルートネストされたフィールドが返され、その一致する内部ネストされたフィールドも返されます。ページネーションはルートネストされたドキュメントで行われ、内部ヒットでは行われません

正規化されたキーワードフィールド

Elasticsearchのkeywordフィールドは、normalizerを定義することで正規化できます。このようなフィールドはElasticsearch SQLではサポートされていません。

配列型フィールド

配列フィールドは、Elasticsearchが値の配列を「見えない」方法で処理するため、サポートされていません:マッピングはフィールドが配列(複数の値を持つ)であるかどうかを示さないため、すべてのデータを読み込まなければ、Elasticsearch SQLはフィールドが単一値か複数値かを知ることができません。フィールドに対して複数の値が返されると、デフォルトではElasticsearch SQLは例外をスローします。ただし、RESTのfield_multi_value_leniencyパラメータ(デフォルトでは無効)またはドライバのfield.multi.value.leniency(デフォルトでは有効)を通じてこの動作を変更することは可能です。

集約によるソート

集約(GROUP BY)を行うとき、Elasticsearch SQLは結果のページネーションをサポートするためにElasticsearchのcomposite集約に依存します。ただし、このタイプの集約には制限があります:ソートは集約のバケットに使用されるキーにのみ適用できます。Elasticsearch SQLはこの制限を克服するためにクライアント側のソートを行いますが、安全策として、最大65535行のみを許可します。

集約によるソートを使用するクエリには、LIMITを使用することをお勧めします。これは、基本的に希望する上位Nの結果を示します:

Sql

  1. SELECT * FROM test GROUP BY age ORDER BY COUNT(*) LIMIT 100;

ただし、LIMITなしで同じクエリを実行することも可能ですが、その場合、最大サイズ(10000)を超えると、例外が返されます。Elasticsearch SQLは返されたすべての結果を追跡(およびソート)できないためです。

さらに、ORDER BYで使用される集約は、プレーンな集約関数のみでなければなりません。スカラー関数や演算子は使用できず、したがって、2つ以上の集約関数を組み合わせた複雑な列を順序付けに使用することはできません。以下は許可されていないクエリのいくつかの例です:

Sql

  1. SELECT age, ROUND(AVG(salary)) AS avg FROM test GROUP BY age ORDER BY avg;
  2. SELECT age, MAX(salary) - MIN(salary) AS diff FROM test GROUP BY age ORDER BY diff;

サブセレクトの使用

サブセレクト(SELECT X FROM (SELECT Y))の使用は小さな範囲でサポートされています:単一のSELECTに「フラット化」できるサブセレクトは、Elasticsearch SQLで可能です。例えば:

Sql

  1. SELECT * FROM (SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%a%') WHERE first_name LIKE 'A%' ORDER BY 1;
  2. first_name | last_name
  3. ---------------+---------------
  4. Alejandro |McAlpine
  5. Anneke |Preusig
  6. Anoosh |Peyn
  7. Arumugam |Ossenbruggen

上記のクエリは、次のように等価であるため可能です:

Sql

  1. SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%a%' AND first_name LIKE 'A%' ORDER BY 1;

しかし、サブセレクトがGROUP BYまたはHAVINGを含む場合、または囲むSELECTSELECT X FROM (SELECT ...) WHERE [simple_condition]よりも複雑な場合、これは現在サポートされていません

HAVING句でのFIRST/LAST集約関数の使用

  1. ## GROUP BYまたはHISTOGRAMでのTIMEデータ型の使用
  2. `````TIME`````データ型をグルーピングキーとして使用することは現在サポートされていません。例えば:
  3. #### Sql
  4. ``````sql
  5. SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME);
  6. `

一方、スカラー関数でラップされて別のデータ型を返す場合は、まだ使用できます。例えば:

Sql

  1. SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME));
  1. #### Sql
  2. ``````sql
  3. SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h
  4. `

地理関連の関数

  1. デフォルトでは、`````geo_points`````フィールドはインデックスされ、ドキュメント値を持っています。ただし、緯度と経度のみが保存され、インデックスされており、元の値からいくつかの精度が失われています(緯度の4.190951585769653E-8および経度の8.381903171539307E-8)。高度成分は受け入れられますが、ドキュメント値に保存されず、インデックスされません。したがって、フィルタリング、グルーピング、またはソートで`````ST_Z`````関数を呼び出すと、`````null`````が返されます。
  2. ## フィールド検索パラメータを使用した取得
  3. Elasticsearch SQLは、[search API`````fields`````パラメータ](1ca72727e8d3ebf9.md#search-fields-param)を使用して列の値を取得します。`````fields`````パラメータに関する制限は、Elasticsearch SQLクエリにも適用されます。例えば、`````_source`````が返されるフィールドまたはインデックスレベルで無効になっている場合、値は取得できません。
  4. ## PIVOT句での集約
  5. [`````PIVOT`````](c1074b455a1012cd.md#sql-syntax-pivot)の集約式は、現在1つの集約のみを受け入れます。したがって、1つのピボット列に対して複数の集約を取得することはできません。
  6. ## PIVOTのINサブ句でのサブクエリの使用
  7. [`````PIVOT`````](c1074b455a1012cd.md#sql-syntax-pivot)クエリがピボットできる値は、リテラルのリストとしてクエリ内で提供する必要があります。このリストを構築するためにサブクエリを提供することは現在サポートされていません。例えば、このクエリでは:
  8. #### Sql
  9. ``````sql
  10. SELECT * FROM test_emp PIVOT (SUM(salary) FOR languages IN (1, 2))
  11. `

関心のあるlanguagesは明示的にリストされる必要があります:IN (1, 2)。一方、この例は機能しません

Sql

  1. SELECT * FROM test_emp PIVOT (SUM(salary) FOR languages IN (SELECT languages FROM test_emp WHERE languages <=2 GROUP BY languages))