SQL 限制

edit

大型查询可能会抛出ParsingException

edit

极大的查询可能会在解析阶段消耗过多内存,在这种情况下,Elasticsearch SQL 引擎将中止解析并抛出错误。在这种情况下,考虑通过简化查询或将其拆分为较小的查询来减小查询的大小。

SYS COLUMNSDESCRIBE TABLE 中的嵌套字段

edit

Elasticsearch 有一种特殊的关系字段类型,称为 nested 字段。在 Elasticsearch SQL 中,可以通过引用它们的内部子字段来使用它们。尽管在非驱动模式(在 CLI 和 REST 调用中)中的 SYS COLUMNSDESCRIBE TABLE 仍然会将它们显示为具有 NESTED 类型,但它们不能在查询中使用。只能以以下形式引用其子字段:

[nested_field_name].[sub_field_name]

例如:

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

不允许在WHEREORDER BY子句中使用嵌套字段上的标量函数

edit

Elasticsearch SQL 不支持在 WHEREORDER BY 子句中对嵌套字段使用标量函数,除了比较和逻辑运算符。

例如:

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

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

不被支持但:

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

受支持。

多层嵌套字段

edit

Elasticsearch 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_Anested_B 不能同时使用,也不能同时使用 nested_A/nested_Bnested_A.nested_X 组合。 对于这种情况,Elasticsearch SQL 将显示一条错误消息。

分页嵌套内部命中

edit

当选择嵌套字段时,分页将不会按预期工作,Elasticsearch SQL 将返回至少页面大小的记录。 这是因为嵌套查询在 Elasticsearch 中的工作方式:将返回根嵌套字段及其匹配的内部嵌套字段, 分页发生在根嵌套文档上,而不是其内部命中

标准化的 keyword 字段

edit

keyword 字段在 Elasticsearch 中可以通过定义一个 normalizer 来进行规范化。此类字段在 Elasticsearch SQL 中不受支持。

字段数组类型

edit

由于Elasticsearch处理值数组的“不可见”方式,不支持数组字段:映射不指示字段是否为数组(具有多个值),因此在读取所有数据之前,Elasticsearch SQL无法知道字段是单值还是多值。当为一个字段返回多个值时,默认情况下,Elasticsearch SQL将抛出异常。然而,可以通过REST中的field_multi_value_leniency参数(默认禁用)或在驱动程序中的field.multi.value.leniency(默认启用)来更改此行为。

按聚合排序

edit

在进行聚合操作(GROUP BY)时,Elasticsearch SQL 依赖于 Elasticsearch 的 composite 聚合来支持结果的分页。 然而,这种类型的聚合确实存在一个限制:只能在用于聚合桶的键上应用排序。 Elasticsearch SQL 通过客户端排序克服了这一限制,但作为一种安全措施,仅允许最多 65535 行。

建议在使用聚合排序的查询中使用LIMIT,本质上是指定所需的顶部N个结果:

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

可以运行相同的查询而不使用LIMIT,但在这种情况下,如果超过了最大大小(10000), 将会返回一个异常,因为Elasticsearch SQL无法跟踪(并排序)所有返回的结果。

此外,在ORDER BY中使用的聚合必须是简单的聚合函数。不能使用标量函数或运算符,因此不能使用结合了两个或多个聚合函数的复杂列进行排序。以下是一些不允许的查询示例:

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;

使用子查询

edit

使用子查询(SELECT X FROM (SELECT Y))在一定程度上是支持的:任何可以“扁平化”为单个SELECT的子查询都可以在Elasticsearch 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

上述查询是可能的,因为它等同于:

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

但是,如果子查询包含 GROUP BYHAVING,或者外层的 SELECTSELECT X FROM (SELECT ...) WHERE [simple_condition] 更复杂,目前这是 不支持的

HAVING子句中使用FIRST/LAST聚合函数

edit

HAVING 子句中使用 FIRSTLAST 是不支持的。当目标列的类型为 keywordunsigned_long 时,MINMAX 也同样适用,因为它们在内部被转换为 FIRSTLAST

在 GROUP BY 或 HISTOGRAM 中使用 TIME 数据类型

edit

使用 TIME 数据类型作为分组键目前不受支持。例如:

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

另一方面,如果它被一个返回另一种数据类型的标量函数包装,它仍然可以使用,例如:

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

TIME 数据类型目前在直方图分组函数中也不受支持。例如:

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

地理相关函数

edit

由于 geo_shape 字段没有文档值,因此这些字段不能用于过滤、分组或排序。

默认情况下,geo_points 字段会被索引并具有文档值。然而,只有纬度和经度被存储和索引,并且会从原始值中损失一些精度(纬度为 4.190951585769653E-8,经度为 8.381903171539307E-8)。高度分量虽然被接受,但不会存储在文档值中,也不会被索引。因此,在过滤、分组或排序中调用 ST_Z 函数将返回 null

使用fields搜索参数进行检索

edit

Elasticsearch SQL 使用 search API 的 fields 参数 来检索列值。fields 参数的任何限制也适用于 Elasticsearch SQL 查询。例如,如果 _source 在任何返回的字段或索引级别被禁用,则无法检索这些值。

PIVOT 子句中的聚合

edit

PIVOT中的聚合表达式目前只接受一个聚合。因此,无法为任何一个透视列获取多个聚合。

PIVOTIN子句中使用子查询

edit

在查询中,PIVOT查询需要旋转的值必须以字面量列表的形式提供;目前不支持使用子查询来构建此列表。例如,在这个查询中:

SELECT * FROM test_emp PIVOT (SUM(salary) FOR languages IN (1, 2))

感兴趣的语言必须明确列出:IN (1, 2)。另一方面,这个例子将不起作用

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