New

The executive guide to generative AI

Read more

SQL 限制

编辑

大型查询可能会抛出 ParsingException

编辑

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

SYS COLUMNSDESCRIBE TABLE 中的嵌套字段

编辑

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 子句中使用嵌套字段上的标量函数

编辑

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;

受支持。

多重嵌套字段

编辑

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 将显示错误消息。

分页嵌套内部命中

编辑

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

规范化的 keyword 字段

编辑

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,本质上是表示所需的 top 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;

使用子查询

编辑

使用子查询 (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 聚合函数

编辑

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

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

编辑

目前不支持使用 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

地理相关函数

编辑

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

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

使用 fields 搜索参数检索

编辑

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

PIVOT 子句中的聚合

编辑

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

PIVOTIN 子句中使用子查询

编辑

PIVOT 查询可以透视的值必须在查询中以字面量列表的形式提供;目前不支持提供子查询来构建此列表。例如,在此查询中

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

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

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