SQLの制限
大きなクエリはParsingExceptionをスローする可能性があります
非常に大きなクエリは、解析フェーズ中にメモリを過剰に消費する可能性があり、その場合、Elasticsearch SQLエンジンは解析を中止し、エラーをスローします。そのような場合は、クエリを簡略化したり、小さなクエリに分割したりして、サイズを小さくすることを検討してください。
SYS COLUMNSおよびDESCRIBE TABLEのネストされたフィールド
Elasticsearchには、nested
フィールドと呼ばれる特別なタイプのリレーションシップフィールドがあります。Elasticsearch SQLでは、内部のサブフィールドを参照することで使用できます。SYS COLUMNS
がドライバーモードでない場合(CLIおよびREST呼び出しで)およびDESCRIBE TABLE
は、NESTED
型として表示されますが、クエリで使用することはできません。サブフィールドは次の形式でのみ参照できます:
Sql
[nested_field_name].[sub_field_name]
例えば:
Sql
SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages;
WHEREおよびORDER BY句でのネストされたフィールドに対するスカラー関数の使用は許可されていません
Elasticsearch SQLは、WHERE
およびORDER BY
句のネストされたフィールドに対するスカラー関数の使用をサポートしていません。比較演算子および論理演算子を除きます。
例えば:
Sql
SELECT * FROM test_emp WHERE LENGTH(dep.dep_name.keyword) > 5;
そして
Sql
SELECT * FROM test_emp ORDER BY YEAR(dep.start_date);
はサポートされていませんが:
Sql
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
column | type | mapping
----------------------+---------------+-------------
nested_A |STRUCT |NESTED
nested_A.nested_X |STRUCT |NESTED
nested_A.nested_X.text|VARCHAR |KEYWORD
nested_A.text |VARCHAR |KEYWORD
nested_B |STRUCT |NESTED
nested_B.text |VARCHAR |KEYWORD
nested_A
とnested_B
は同時に使用できず、nested_A
/nested_B
とnested_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
SELECT * FROM test GROUP BY age ORDER BY COUNT(*) LIMIT 100;
ただし、LIMIT
なしで同じクエリを実行することも可能ですが、その場合、最大サイズ(10000)を超えると、例外が返されます。Elasticsearch SQLは返されたすべての結果を追跡(およびソート)できないためです。
さらに、ORDER BY
で使用される集約は、プレーンな集約関数のみでなければなりません。スカラー関数や演算子は使用できず、したがって、2つ以上の集約関数を組み合わせた複雑な列を順序付けに使用することはできません。以下は許可されていないクエリのいくつかの例です:
Sql
SELECT age, ROUND(AVG(salary)) AS avg FROM test GROUP BY age ORDER BY avg;
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
SELECT * FROM (SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%a%') WHERE first_name LIKE 'A%' ORDER BY 1;
first_name | last_name
---------------+---------------
Alejandro |McAlpine
Anneke |Preusig
Anoosh |Peyn
Arumugam |Ossenbruggen
上記のクエリは、次のように等価であるため可能です:
Sql
SELECT first_name, last_name FROM emp WHERE last_name NOT LIKE '%a%' AND first_name LIKE 'A%' ORDER BY 1;
しかし、サブセレクトがGROUP BY
またはHAVING
を含む場合、または囲むSELECT
がSELECT X
FROM (SELECT ...) WHERE [simple_condition]
よりも複雑な場合、これは現在サポートされていません。
HAVING句でのFIRST/LAST集約関数の使用
## GROUP BYまたはHISTOGRAMでのTIMEデータ型の使用
`````TIME`````データ型をグルーピングキーとして使用することは現在サポートされていません。例えば:
#### Sql
``````sql
SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME);
`
一方、スカラー関数でラップされて別のデータ型を返す場合は、まだ使用できます。例えば:
Sql
SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME));
#### Sql
``````sql
SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h
`
地理関連の関数
デフォルトでは、`````geo_points`````フィールドはインデックスされ、ドキュメント値を持っています。ただし、緯度と経度のみが保存され、インデックスされており、元の値からいくつかの精度が失われています(緯度の4.190951585769653E-8および経度の8.381903171539307E-8)。高度成分は受け入れられますが、ドキュメント値に保存されず、インデックスされません。したがって、フィルタリング、グルーピング、またはソートで`````ST_Z`````関数を呼び出すと、`````null`````が返されます。
## フィールド検索パラメータを使用した取得
Elasticsearch SQLは、[search APIの`````fields`````パラメータ](1ca72727e8d3ebf9.md#search-fields-param)を使用して列の値を取得します。`````fields`````パラメータに関する制限は、Elasticsearch SQLクエリにも適用されます。例えば、`````_source`````が返されるフィールドまたはインデックスレベルで無効になっている場合、値は取得できません。
## PIVOT句での集約
[`````PIVOT`````](c1074b455a1012cd.md#sql-syntax-pivot)の集約式は、現在1つの集約のみを受け入れます。したがって、1つのピボット列に対して複数の集約を取得することはできません。
## PIVOTのINサブ句でのサブクエリの使用
[`````PIVOT`````](c1074b455a1012cd.md#sql-syntax-pivot)クエリがピボットできる値は、リテラルのリストとしてクエリ内で提供する必要があります。このリストを構築するためにサブクエリを提供することは現在サポートされていません。例えば、このクエリでは:
#### Sql
``````sql
SELECT * FROM test_emp PIVOT (SUM(salary) FOR languages IN (1, 2))
`
関心のあるlanguages
は明示的にリストされる必要があります:IN (1, 2)
。一方、この例は機能しません:
Sql
SELECT * FROM test_emp PIVOT (SUM(salary) FOR languages IN (SELECT languages FROM test_emp WHERE languages <=2 GROUP BY languages))