SQL 限制
editSQL 限制
edit大型查询可能会抛出ParsingException
edit极大的查询可能会在解析阶段消耗过多内存,在这种情况下,Elasticsearch SQL 引擎将中止解析并抛出错误。在这种情况下,考虑通过简化查询或将其拆分为较小的查询来减小查询的大小。
SYS COLUMNS 和 DESCRIBE TABLE 中的嵌套字段
editElasticsearch 有一种特殊的关系字段类型,称为 nested 字段。在 Elasticsearch SQL 中,可以通过引用它们的内部子字段来使用它们。尽管在非驱动模式(在 CLI 和 REST 调用中)中的 SYS COLUMNS 和 DESCRIBE TABLE 仍然会将它们显示为具有 NESTED 类型,但它们不能在查询中使用。只能以以下形式引用其子字段:
[nested_field_name].[sub_field_name]
例如:
SELECT dep.dep_name.keyword FROM test_emp GROUP BY languages;
不允许在WHERE和ORDER BY子句中使用嵌套字段上的标量函数
editElasticsearch SQL 不支持在 WHERE 和 ORDER 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;
受支持。
多层嵌套字段
editElasticsearch 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 将显示一条错误消息。
分页嵌套内部命中
edit当选择嵌套字段时,分页将不会按预期工作,Elasticsearch SQL 将返回至少页面大小的记录。 这是因为嵌套查询在 Elasticsearch 中的工作方式:将返回根嵌套字段及其匹配的内部嵌套字段, 分页发生在根嵌套文档上,而不是其内部命中。
标准化的 keyword 字段
editkeyword 字段在 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 BY 或 HAVING,或者外层的 SELECT 比 SELECT X
FROM (SELECT ...) WHERE [simple_condition] 更复杂,目前这是 不支持的。
在 HAVING 子句中使用 FIRST 和 LAST 是不支持的。当目标列的类型为 keyword 或 unsigned_long 时,MIN 和 MAX 也同样适用,因为它们在内部被转换为 FIRST 和 LAST。
使用 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搜索参数进行检索
editElasticsearch SQL 使用 search API 的
fields 参数 来检索列值。fields 参数的任何限制也适用于
Elasticsearch SQL 查询。例如,如果 _source 在任何返回的字段或索引级别被禁用,则无法检索这些值。
在PIVOT中的聚合表达式目前只接受一个聚合。因此,无法为任何一个透视列获取多个聚合。
在查询中,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))