ALL(cond FOR var IN json.array) применяется к JSON-массивам и возвращает 1, если условие истинно для всех элементов массива, и 0 в противном случае. cond — это общее выражение, которое также может использовать var как текущее значение элемента массива внутри себя.
- ALL() with json
- ALL() with json ex. 2
select *, ALL(x>0 AND x<4 FOR x IN j.ar) from tbl+------+--------------+--------------------------------+
| id | j | all(x>0 and x<4 for x in j.ar) |
+------+--------------+--------------------------------+
| 1 | {"ar":[1,3]} | 1 |
| 2 | {"ar":[3,7]} | 0 |
+------+--------------+--------------------------------+
2 rows in set (0.00 sec)ALL(mva) — это специальный конструктор для мультизначных атрибутов. При использовании с операторами сравнения (включая сравнение с IN()), он возвращает 1, если все значения из MVA-атрибута найдены среди сравниваемых значений.
- ALL() with MVA
- ALL() with MVA and IN()
select * from tbl where all(m) >= 1+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)Для сравнения MVA-атрибута с массивом избегайте использования <mva> NOT ALL(); вместо этого используйте ALL(<mva>) NOT IN().
- ALL() with MVA and NOT IN()
select * from tbl where all(m) not in (2, 4)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)ALL(string list) — это специальная операция для фильтрации строковых тегов.
Если все слова, перечисленные в аргументах ALL(), присутствуют в атрибуте, фильтр срабатывает. Опциональный NOT инвертирует логику.
Этот фильтр внутренне использует пословное сопоставление, поэтому в случае полного сканирования запрос может работать медленнее, чем ожидалось. Он предназначен для атрибутов, которые не индексируются, например, вычисляемых выражений или тегов в PQ-таблицах. Если вам нужна такая фильтрация, рассмотрите вариант размещения строкового атрибута как полнотекстового поля, а затем используйте полнотекстовый оператор match(), который вызовет полнотекстовый поиск.
- ALL() with strings
- ALL() with strings and NOT
select * from tbl where tags all('bug', 'release')+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)ANY(cond FOR var IN json.array) применяется к JSON-массивам и возвращает 1, если условие истинно для любого элемента массива, и 0 в противном случае. cond — это общее выражение, которое также может использовать var как текущее значение элемента массива внутри себя.
- ANY() with json
- ANY() with json ex. 2
select *, ANY(x>5 AND x<10 FOR x IN j.ar) from tbl+------+--------------+---------------------------------+
| id | j | any(x>5 and x<10 for x in j.ar) |
+------+--------------+---------------------------------+
| 1 | {"ar":[1,3]} | 0 |
| 2 | {"ar":[3,7]} | 1 |
+------+--------------+---------------------------------+
2 rows in set (0.00 sec)ANY(mva) — это специальный конструктор для мультизначных атрибутов. При использовании с операторами сравнения (включая сравнение с IN()), он возвращает 1, если любое из значений MVA найдено среди сравниваемых значений.
При сравнении массива с помощью IN() по умолчанию предполагается ANY(), если не указано иное, но будет выдано предупреждение о пропущенном конструкторе.
- ANY() with MVA
- ANY() with MVA and IN()
mysql> select * from tbl
+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.01 sec)
mysql> select * from tbl where any(m) > 5
+------+------+
| id | m |
+------+------+
| 2 | 3,7 |
+------+------+
1 row in set (0.00 sec)+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)Для сравнения MVA-атрибута с массивом избегайте использования <mva> NOT ANY(); вместо этого используйте <mva> NOT IN() или ANY(<mva>) NOT IN().
- ANY() with MVA and NOT IN()
mysql> select * from tbl
+------+------+
| id | m |
+------+------+
| 1 | 1,3 |
| 2 | 3,7 |
+------+------+
2 rows in set (0.00 sec)
mysql> select * from tbl where any(m) not in (1, 3, 5)
+------+------+
| id | m |
+------+------+
| 2 | 3,7 |
+------+------+
1 row in set (0.00 sec)ANY(string list) — это специальная операция для фильтрации строковых тегов.
Если любое из слов, перечисленных в аргументах ANY(), присутствует в атрибуте, фильтр срабатывает. Опциональный NOT инвертирует логику.
Этот фильтр внутренне использует пословное сопоставление, поэтому в случае полного сканирования запрос может работать медленнее, чем ожидалось. Он предназначен для атрибутов, которые не индексируются, например, вычисляемых выражений или тегов в PQ-таблицах. Если вам нужна такая фильтрация, рассмотрите вариант размещения строкового атрибута как полнотекстового поля, а затем используйте полнотекстовый оператор match(), который вызовет полнотекстовый поиск.
- ANY() with strings
- ANY() with strings and NOT
select * from tbl where tags any('bug', 'feature')+------+---------------------------+
| id | tags |
+------+---------------------------+
| 1 | bug priority_high release |
| 2 | bug priority_low release |
+------+---------------------------+
2 rows in set (0.00 sec)CONTAINS(polygon, x, y) проверяет, находится ли точка (x,y) внутри заданного полигона, и возвращает 1, если да, или 0, если нет. Полигон должен быть задан с помощью функции POLY2D(). Эта функция предназначена для "маленьких" полигонов, то есть со стороной менее 500 км (300 миль), и не учитывает кривизну Земли для ускорения. Для больших расстояний следует использовать GEOPOLY2D, который разбивает заданный полигон на меньшие части с учётом кривизны Земли.
Поведение IF() немного отличается от аналога в MySQL. Он принимает 3 аргумента, проверяет, равен ли первый аргумент 0.0, возвращает второй аргумент, если он не равен нулю, или третий, если равен. Обратите внимание, что в отличие от операторов сравнения, IF() не использует порог! Поэтому безопасно использовать результаты сравнений в качестве первого аргумента, но арифметические операторы могут давать неожиданные результаты. Например, следующие два вызова дадут разные результаты, хотя логически эквивалентны:
- IF()
IF ( sqrt(3)*sqrt(3)-3<>0, a, b )
IF ( sqrt(3)*sqrt(3)-3, a, b )В первом случае оператор сравнения <> вернёт 0.0 (ложь) из-за порога, и IF() всегда вернёт ** как результат. Во втором случае выражение sqrt(3)*sqrt(3)-3 будет сравниваться с нулём без порога самой функцией IF(). Однако его значение будет немного отличаться от нуля из-за ограниченной точности вычислений с плавающей точкой. Из-за этого сравнение с 0.0, выполненное IF(), не пройдёт, и второй вариант вернёт 'a' как результат.
HISTOGRAM(expr, {hist_interval=size, hist_offset=value}) принимает размер корзины и возвращает номер корзины для значения. Ключевая функция:
key_of_the_bucket = interval + offset * floor ( ( value - offset ) / interval )
Аргумент гистограммы interval должен быть положительным. Аргумент гистограммы offset должен быть положительным и меньше interval. Он используется в агрегации, FACET и группировке.
- HISTOGRAM()
SELECT COUNT(*),
HISTOGRAM(price, {hist_interval=100}) as price_range
FROM facets
GROUP BY price_range ORDER BY price_range ASC;IN(expr,val1,val2,...) принимает 2 или более аргументов и возвращает 1, если первый аргумент (expr) равен любому из других аргументов (val1..valN), или 0 в противном случае. В настоящее время все проверяемые значения (но не само выражение) должны быть константами. Константы предварительно сортируются, и используется бинарный поиск, поэтому IN() даже при большом произвольном списке констант будет очень быстрым. Первый аргумент также может быть атрибутом MVA. В этом случае IN() вернет 1, если любое из значений MVA равно любому из других аргументов. IN() также поддерживает синтаксис IN(expr,@uservar) для проверки, принадлежит ли значение списку в данном глобальном пользовательском переменном. Первый аргумент может быть JSON-атрибутом.
Функция INDEXOF(cond FOR var IN json.array) перебирает все элементы массива и возвращает индекс первого элемента, для которого 'cond' истинно, и -1, если 'cond' ложно для каждого элемента массива.
INTERVAL(expr,point1,point2,point3,...) принимает 2 или более аргументов и возвращает индекс аргумента, который меньше первого аргумента: возвращает 0, если expr<point1, 1, если point1<=expr<point2 и так далее. Для корректной работы функции требуется, чтобы point1<point2<...<pointN.
Функция LENGTH(attr_mva) возвращает количество элементов в наборе MVA. Она работает как с 32-битными, так и с 64-битными атрибутами MVA. LENGTH(attr_json) возвращает длину поля в JSON. Возвращаемое значение зависит от типа поля. Например, LENGTH(json_attr.some_int) всегда возвращает 1, а LENGTH(json_attr.some_array) возвращает количество элементов в массиве. Функция LENGTH(string_expr) возвращает длину строки, полученной из выражения.
TO_STRING() должна обрамлять выражение, независимо от того, возвращает ли выражение нестроковое значение или это просто строковый атрибут.
RANGE(expr, {range_from=value,range_to=value}) принимает набор диапазонов и возвращает номер корзины для значения.
Это выражение включает значение range_from и исключает значение range_to для каждого диапазона. Диапазон может быть открытым — иметь только значение range_from или только range_to. Используется в агрегации, FACET и группировке.
- RANGE()
SELECT COUNT(*),
RANGE(price, {range_to=150},{range_from=150,range_to=300},{range_from=300}) price_range
FROM facets
GROUP BY price_range ORDER BY price_range ASC;Функция REMAP(condition, expression, (cond1, cond2, ...), (expr1, expr2, ...)) позволяет делать некоторые исключения для значений выражения в зависимости от значений условия. Выражение условия всегда должно возвращать целое число, в то время как выражение может возвращать целое число или число с плавающей точкой.
- REMAP()
- Another example
SELECT id, size, REMAP(size, 15, (5,6,7,8), (1,1,2,2)) s
FROM products
ORDER BY s ASC;Это поместит документы с размерами 5 и 6 первыми, за ними последуют размеры 7 и 8. В случае, если есть исходное значение, не указанное в массиве (например, размер 10), оно по умолчанию будет равно 15 и в этом случае будет размещено в конце.