Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›SQL

Ограничения SQL

Большие запросы могут привести к ParsingException

Очень большие запросы могут потреблять слишком много памяти во время фазы парсинга, в этом случае движок Elasticsearch SQL прервет парсинг и выдаст ошибку. В таких случаях рассмотрите возможность уменьшения размера запроса, потенциально упростив его или разделив его на несколько меньших запросов.

Вложенные поля в SYS COLUMNS и DESCRIBE TABLE

Elasticsearch имеет особый тип полей отношений, называемых полями nested. В Elasticsearch SQL они могут быть использованы путем ссылки на их внутренние подполя. Несмотря на то, что SYS COLUMNS в режиме без драйвера (в командной строке и в REST-вызовах) и DESCRIBE TABLE все равно будут отображать их как имеющие тип NESTED, они не могут быть использованы в запросе. Можно ссылаться только на его подполя в формате:

[nested_field_name].[sub_field_name]

Например:

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

Скалярные функции над вложенными полями не разрешены в WHERE и ORDER BY клаузах

Elasticsearch 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;

поддерживаются.

Многоуровневые вложенные поля

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_A и nested_B не могут быть использованы одновременно, также как и nested_A/nested_B и nested_A.nested_X комбинации. В таких ситуациях Elasticsearch SQL выведет сообщение об ошибке.

Пейджинг вложенных внутренних результатов

При SELECT вложенного поля пейджинг не будет работать как ожидается, Elasticsearch SQL вернёт как минимум количество записей, заданное размером страницы. Это связано с тем, как работают вложенные запросы в Elasticsearch: корневое вложенное поле будет возвращено, а также соответствующие ему внутренние вложенные поля, при этом пейджинг происходит на корневом вложенном документе, а не на его внутренних результатах.

Нормализованные поля keyword

Поля keyword в Elasticsearch могут быть нормализованы путём определения normalizer. Такие поля не поддерживаются в Elasticsearch SQL.

Поля типа массив

Поля типа массив не поддерживаются из-за "скрытого" способа обработки массива значений в Elasticsearch: отображение не указывает, является ли поле массивом (имеет несколько значений) или нет, поэтому Elasticsearch SQL не может узнать, является ли поле однозначным или многозначным без чтения всех данных. Если для поля возвращается несколько значений, Elasticsearch SQL по умолчанию генерирует исключение. Однако возможно изменить это поведение через параметр field_multi_value_leniency в REST (выключено по умолчанию) или field.multi.value.leniency в драйверах (включено по умолчанию).

Сортировка по агрегации

При выполнении агрегаций (GROUP BY) Elasticsearch SQL полагается на Elasticsearch's агрегацию composite для поддержки пейджинга результатов. Однако этот тип агрегации имеет ограничение: сортировка может быть применена только к ключу, используемому для корзинок агрегации. Elasticsearch SQL преодолевает это ограничение, выполняя сортировку на стороне клиента, но в качестве меры предосторожности, разрешает только до 65535 строк.

Рекомендуется использовать LIMIT для запросов, использующих сортировку по агрегации, по существу указывая количество верхних результатов, которые требуется получить:

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 BY или HAVING, или окружающая SELECT будет более сложной, чем SELECT X FROM (SELECT ...) WHERE [simple_condition], это в настоящее время не поддерживается.

Использование агрегирующих функций FIRST/LAST в HAVING клаузе

Использование FIRST и LAST в клаузе HAVING не поддерживается. То же самое относится к MIN и MAX, когда их целевой столбец имеет тип keyword или unsigned_long, так как они переводятся во внутреннем представлении в FIRST и LAST.

Использование типа данных TIME в GROUP BY или HISTOGRAM

Использование типа данных 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 не имеют значений документов, эти поля не могут быть использованы для фильтрации, группировки или сортировки.

По умолчанию, поля geo_points индексируются и имеют значения документов. Однако хранятся и индексируются только широта и долгота с некоторыми потерями точности по отношению к исходным значениям (4.190951585769653E-8 для широты и 8.381903171539307E-8 для долготы). Компонент высоты принимается, но не хранится в значениях документов и не индексируется. Поэтому вызов функции ST_Z в фильтрации, группировке или сортировке вернёт null.

Получение данных с помощью параметра поиска fields

Elasticsearch SQL извлекает значения столбцов с помощью параметра fields API поиска. Любые ограничения на параметр fields также применимы к запросам Elasticsearch SQL. Например, если _source отключён для любого из возвращаемых полей или на уровне индекса, значения не могут быть получены.

Агрегации в клаузе PIVOT

Выражение агрегации в PIVOT в настоящее время допускает только одну агрегацию. Таким образом, получить несколько агрегаций для одного столбца нет возможности.

Использование подзапроса в подклаузе PIVOT's IN

Значения, которые запрос 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))

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/sql-limitations.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API