SQL Limitations

edit

Large queries may throw ParsingExpection

edit

Extremely large queries can consume too much memory during the parsing phase, in which case the Elasticsearch SQL engine will abort parsing and throw an error. In such cases, consider reducing the query to a smaller size by potentially simplifying it or splitting it into smaller queries.

Nested fields in SYS COLUMNS and DESCRIBE TABLE

edit

Elasticsearch has a special type of relationship fields called nested fields. In Elasticsearch SQL they can be used by referencing their inner sub-fields. Even though SYS COLUMNS in non-driver mode (in the CLI and in REST calls) and DESCRIBE TABLE will still display them as having the type NESTED, they cannot be used in a query. One can only reference its sub-fields in the form:

[nested_field_name].[sub_field_name]

For example:

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

Multi-nested fields

edit

Elasticsearch SQL doesn’t support multi-nested documents, so a query cannot reference more than one nested field in an index. This applies to multi-level nested fields, but also multiple nested fields defined on the same level. For example, for this index:

       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 and nested_B cannot be used at the same time, nor nested_A/nested_B and nested_A.nested_X combination. For such situations, Elasticsearch SQL will display an error message.

Paginating nested inner hits

edit

When SELECTing a nested field, pagination will not work as expected, Elasticsearch SQL will return at least the page size records. This is because of the way nested queries work in Elasticsearch: the root nested field will be returned and it’s matching inner nested fields as well, pagination taking place on the root nested document and not on its inner hits.

Normalized keyword fields

edit

keyword fields in Elasticsearch can be normalized by defining a normalizer. Such fields are not supported in Elasticsearch SQL.

Array type of fields

edit

Array fields are not supported due to the "invisible" way in which Elasticsearch handles an array of values: the mapping doesn’t indicate whether a field is an array (has multiple values) or not, so without reading all the data, Elasticsearch SQL cannot know whether a field is a single or multi value. When multiple values are returned for a field, by default, Elasticsearch SQL will throw an exception. However, it is possible to change this behavior through field_multi_value_leniency parameter in REST (disabled by default) or field.multi.value.leniency in drivers (enabled by default).

Sorting by aggregation

edit

When doing aggregations (GROUP BY) Elasticsearch SQL relies on Elasticsearch’s composite aggregation for its support for paginating results. However this type of aggregation does come with a limitation: sorting can only be applied on the key used for the aggregation’s buckets. Elasticsearch SQL overcomes this limitation by doing client-side sorting however as a safety measure, allows only up to 512 rows.

It is recommended to use LIMIT for queries that use sorting by aggregation, essentially indicating the top N results that are desired:

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

It is possible to run the same queries without a LIMIT however in that case if the maximum size (10000) is passed, an exception will be returned as Elasticsearch SQL is unable to track (and sort) all the results returned.

Using aggregation functions on top of scalar functions

edit

Aggregation functions like MIN, MAX, etc. can only be used directly on fields, and so queries like SELECT MAX(abs(age)) FROM test are not possible.

Using a sub-select

edit

Using sub-selects (SELECT X FROM (SELECT Y)) is supported to a small degree: any sub-select that can be "flattened" into a single SELECT is possible with Elasticsearch SQL. For example:

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

The query above is possible because it is equivalent with:

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

But, if the sub-select would include a GROUP BY or HAVING or the enclosing SELECT would be more complex than SELECT X FROM (SELECT ...) WHERE [simple_condition], this is currently un-supported.

Using FIRST/LAST aggregation functions in HAVING clause

edit

Using FIRST and LAST in the HAVING clause is not supported. The same applies to MIN and MAX when their target column is of type keyword as they are internally translated to FIRST and LAST.

Using TIME data type in GROUP BY or HISTOGRAM

edit

Using TIME data type as a grouping key is currently not supported. For example:

SELECT count(*) FROM test GROUP BY CAST(date_created AS TIME);

On the other hand, it can still be used if it’s wrapped with a scalar function that returns another data type, for example:

SELECT count(*) FROM test GROUP BY MINUTE((CAST(date_created AS TIME));

TIME data type is also currently not supported in histogram grouping function. For example:

SELECT HISTOGRAM(CAST(birth_date AS TIME), INTERVAL '10' MINUTES) as h, COUNT(*) FROM t GROUP BY h

Geo-related functions

edit

Since geo_shape fields don’t have doc values these fields cannot be used for filtering, grouping or sorting.

By default,geo_points fields are indexed and have doc values. However only latitude and longitude are stored and indexed with some loss of precision from the original values (4.190951585769653E-8 for the latitude and 8.381903171539307E-8 for longitude). The altitude component is accepted but not stored in doc values nor indexed. Therefore calling ST_Z function in the filtering, grouping or sorting will return null.