Перейти к содержанию

Операторы

AQL поддерживает ряд операторов, которые можно использовать в выражениях. Есть сравнение, логический, арифметический и тернарный оператор.

Операторы сравнения

Операторы сравнения (или отношения) сравнивают два операнда. Их можно использовать с любыми типами входных данных и возвращать логическое значение результата.

Поддерживаются следующие операторы сравнения:

Оператор Описание
== равенство
!= неравенство
< меньше чем
<= меньше или равно
> больше чем
>= больше или равно
IN проверить, содержится ли значение в массиве
NOT IN проверить, не содержится ли значение в массиве
LIKE проверяет, соответствует ли строковое значение шаблону
NOT LIKE проверяет, не соответствует ли строковое значение шаблону
=~ проверяет, соответствует ли строковое значение регулярному выражению
!~ проверяет, не соответствует ли строковое значение регулярному выражению

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

Операторы сравнения принимают любые типы данных для первого и второго операндов. Однако операторы IN и NOT IN возвращают осмысленный результат только в том случае, если их правый операнд является массивом. LIKE и NOT LIKE выполняются, только если оба операнда являются строковыми значениями. Все четыре оператора не выполняют неявное приведение типов, если сравниваемые операнды имеют разные типы, т. е. они проверяют строгое равенство или неравенство (например, 0 отличается от "0", [0], false и null).

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
     0  ==  null            // false
     1  >   0               // true
  true  !=  null            // true
    45  <=  "yikes!"        // true
    65  !=  "65"            // true
    65  ==  65              // true
  1.23  >   1.32            // false
   1.5  IN  [ 2, 3, 1.5 ]   // true
 "foo"  IN  null            // false
42  NOT IN  [ 17, 40, 50 ]  // true
 "abc"  ==  "abc"           // true
 "abc"  ==  "ABC"           // false
 "foo"  LIKE  "f%"          // true
 "foo"  NOT LIKE  "f%"      // false
 "foo"  =~  "^f[o].$"       // true
 "foo"  !~  "[a-z]+bar$"    // true

Оператор LIKE проверяет, соответствует ли его левый операнд шаблону, указанному в его правом операнде. Шаблон может состоять из обычных символов и подстановочных знаков. Поддерживаемые подстановочные знаки: _ для соответствия одному произвольному символу и % для соответствия любому количеству произвольных символов. Буквенные % и _ должны быть экранированы обратной косой чертой. Обратная косая черта должна быть экранирована, что фактически означает, что два символа обратной косой черты должны предшествовать буквальному знаку процента или подчеркиванию. В арангоше требуется дополнительное экранирование, в результате чего всего четыре обратной косой черты предшествуют символу, который нужно экранировать.

1
2
3
    "abc" LIKE "a%"          // true
    "abc" LIKE "_bc"         // true
"a_b_foo" LIKE "a\\_b\\_foo" // true

Сопоставление с образцом, выполняемое оператором LIKE, чувствительно к регистру.

Оператор NOT LIKE имеет те же характеристики, что и оператор LIKE, но с отрицательным результатом. Таким образом, оно идентично NOT (… LIKE …). Обратите внимание на круглые скобки, необходимые для некоторых выражений:

1
2
FOR doc IN coll
  RETURN NOT doc.attr LIKE "…"

Возвращаемое выражение преобразуется в LIKE(!doc.attr, "…"), что приводит к неожиданным результатам. NOT(doc.attr LIKE "…") превращается в более разумный ! LIKE(doc.attr, "…").

Операторы регулярных выражений =~ и !~ ожидают, что их левые операнды будут строками, а их правые операнды будут строками, содержащими допустимые регулярные выражения, как указано в документации для функции AQL REGEX_TEST().

Операторы сравнения массивов

Большинство операторов сравнения также существуют в виде варианта массива. В варианте с массивом оператор ==, !=, >, >=, <, <=, IN или NOT IN имеет префикс с ключевым словом ALL, ANY или NONE. Это изменяет поведение оператора для сравнения отдельных элементов массива левого аргумента с правым аргументом. В зависимости от ключевого слова, определяющего количественную оценку, все, любые или ни одно из этих сравнений должны быть удовлетворены, чтобы в целом оценка была истинной.

Вы также можете комбинировать один из поддерживаемых операторов сравнения со специальным оператором AT LEAST (<выражение>), чтобы потребовать, чтобы произвольное количество элементов удовлетворяло условию, чтобы оценка была true. Вы можете использовать статическое число или вычислить его динамически с помощью выражения.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
[ 1, 2, 3 ]  ALL IN  [ 2, 3, 4 ]  // false
[ 1, 2, 3 ]  ALL IN  [ 1, 2, 3 ]  // true
[ 1, 2, 3 ]  NONE IN  [ 3 ]       // false
[ 1, 2, 3 ]  NONE IN  [ 23, 42 ]  // true
[ 1, 2, 3 ]  ANY IN  [ 4, 5, 6 ]  // false
[ 1, 2, 3 ]  ANY IN  [ 1, 42 ]    // true
[ 1, 2, 3 ]  ANY ==  2            // true
[ 1, 2, 3 ]  ANY ==  4            // false
[ 1, 2, 3 ]  ANY >  0             // true
[ 1, 2, 3 ]  ANY <=  1            // true
[ 1, 2, 3 ]  NONE <  99           // false
[ 1, 2, 3 ]  NONE >  10           // true
[ 1, 2, 3 ]  ALL >  2             // false
[ 1, 2, 3 ]  ALL >  0             // true
[ 1, 2, 3 ]  ALL >=  3            // false
["foo", "bar"]  ALL !=  "moo"     // true
["foo", "bar"]  NONE ==  "bar"    // false
["foo", "bar"]  ANY ==  "foo"     // true

[ 1, 2, 3 ]  AT LEAST (2) IN  [ 2, 3, 4 ]  // true
["foo", "bar"]  AT LEAST (1+1) ==  "foo"   // false

Обратите внимание, что эти операторы не используют индексы в обычных запросах. Операторы также поддерживаются в выражениях SEARCH, где можно использовать индексы ArangoSearch. Однако семантика различается, см. операцию AQL SEARCH.

Логические операторы

В AQL поддерживаются следующие логические операторы:

  • && логический оператор И
  • || логический оператор ИЛИ
  • ! логический оператор НЕ

AQL также поддерживает следующие альтернативные формы логических операторов:

  • AND логический оператор И
  • OR логический оператор ИЛИ
  • NOT логический оператор НЕ

Альтернативные формы являются псевдонимами и функционально эквивалентны обычным операторам.

Логические операторы с двумя операндами в AQL выполняются с кратким вычислением (за исключением случаев, когда один из операндов является подзапросом или включает его. В этом случае подзапрос извлекается и оценивается перед логическим оператором).

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

  • lhs && rhs возвращает lhs, если оно false или было бы false при преобразовании в логическое значение. Если левое значение истинно или могло бы быть истинным при преобразовании в логическое значение, возвращается правое значение.
  • lhs || rhs возвращает lhs, если оно истинно или было бы истинным при преобразовании в логическое значение. Если lhs имеет значение false или будет ложным при преобразовании в логическое значение, возвращается rhs.
  • ! value возвращает инвертированное значение value, преобразованное в логическое значение.
1
2
3
4
u.age > 15 && u.address.city != ""
true || false
NOT u.isInvalid
1 || ! 0

Передача небулевых значений логическому оператору разрешена. Любые нелогические операнды неявно преобразуются оператором в логические, не прерывая выполнение запроса.

Преобразование в логическое значение работает следующим образом:

  • null преобразуется в false
  • логические значения остаются неизменными
  • все числа не равные нулю истинны, ноль ложен
  • пустая строка ложна, все остальные строки верны
  • массивы ([]) и объекты/документы ({}) истинны, независимо от их содержимого

Результат операций логического И и логического ИЛИ теперь может иметь любой тип данных и не обязательно является логическим значением.

Например, следующие логические операции возвращают логические значения:

1
2
3
25 > 1  &&  42 != 7                        // true
22 IN [ 23, 42 ]  ||  23 NOT IN [ 22, 7 ]  // true
25 != 25                                   // false

… тогда как следующие логические операции не возвращают логические значения:

1
2
3
4
   1 || 7                                  // 1
null || "foo"                              // "foo"
null && true                               // null
true && 23                                 // 23

Арифметические операторы

Арифметические операторы выполняют арифметическую операцию над двумя числовыми операндами. Результатом арифметической операции снова является числовое значение.

AQL поддерживает следующие арифметические операторы:

  • + сложение
  • - разность
  • * умножение
  • / деление
  • % деление по модулю

Унарный плюс и унарный минус также поддерживаются:

1
2
3
4
LET x = -5
LET y = 1
RETURN [-x, +y]
// [5, 1]

Для возведения в степень есть числовая функция POW(). Синтаксис base ** exp не поддерживается.

Для конкатенации строк необходимо использовать строковую функцию CONCAT(). Объединение двух строк с помощью оператора "плюс" ("foo" + "bar") не работает!

1
2
3
4
5
6
7
1 + 1
33 - 99
12.4 * 4.5
13.0 / 0.1
23 % 7
-15
+9.99

Арифметические операторы принимают операнды любого типа. При передаче нечисловых значений арифметическому оператору операнды приводятся к числам с использованием правил приведения типов, применяемых функцией TO_NUMBER():

  • null преобразуется в 0
  • false преобразуется в 0, true преобразуется в 1
  • допустимое числовое значение остается неизменным, но NaN и Infinity преобразуются в 0
  • строковые значения преобразуются в число, если они содержат допустимое строковое представление числа. Любые пробелы в начале или в конце строки игнорируются. Строки с любым другим содержимым преобразуются в число 0
  • пустой массив преобразуется в 0, массив с одним элементом преобразуется в числовое представление его единственного элемента. Массивы с большим количеством элементов преобразуются в число 0.
  • объекты/документы преобразуются в число 0.

Арифметическая операция, которая дает недопустимое значение, такое как 1 / 0 (деление на ноль), возвращает значение null. Запрос не прерывается, но вы можете увидеть предупреждение.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
   1 + "a"       // 1
   1 + "99"      // 100
   1 + null      // 1
null + 1         // 1
   3 + [ ]       // 3
  24 + [ 2 ]     // 26
  24 + [ 2, 4 ]  // 24
  25 - null      // 25
  17 - true      // 16
  23 * { }       // 0
   5 * [ 7 ]     // 35
  24 / "12"      // 2
   1 / 0         // null (with a 'division by zero' warning)

Тернарный оператор

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

В следующем примере выражение возвращает u.userId, если u.age больше 15 или если u.active имеет значение true. В противном случае он возвращает null:

1
u.age > 15 || u.active == true ? u.userId : null

Существует также сокращенный вариант тернарного оператора всего с двумя операндами. Этот вариант можно использовать, если выражение для логического условия и возвращаемое значение должны совпадать.

В следующем примере выражение оценивается как u.value, если u.value истинно. В противном случае возвращается фиксированная строка:

1
u.value ? : 'value is null, 0 or not present'

Условие (здесь просто u.value) оценивается только один раз, если второй операнд между ? и : опущено, тогда как в случае u.value ? u.value : 'value is null'.

Подзапросы, используемые внутри выражений, извлекаются из этих выражений и выполняются заранее. Это означает, что подзапросы не участвуют в ленивом вычислении операндов, например, в тернарном операторе. См. также оценку подзапросов.

Оператор диапазона

AQL поддерживает выражение простых числовых диапазонов с помощью оператора ... Этот оператор можно использовать для простого перебора последовательности числовых значений.

Оператор .. создает массив целочисленных значений в определенном диапазоне, включая оба ограничивающих значения.

1
2010..2013

Приведенный выше пример дает следующий результат:

1
[2010, 2011, 2012, 2013]

Использование оператора диапазона эквивалентно записи массива с целочисленными значениями в диапазоне, заданном границами диапазона. Если границы оператора диапазона не являются целыми числами, они сначала преобразуются в целые значения.

Существует также функция RANGE().

Операторы массива

AQL предоставляет различные операторы массива:

Оператор приоритета

Приоритет операций в AQL такой же, как и в других знакомых языках (сначала наивысший приоритет):

Оператор Описание
:: область действия (определяемые пользователем функции AQL)
[*] расширение массива
[] доступ к индексированным значениям (массивов)
. членский доступ (объектов)
() вызов функции
!, NOT, +, - унарное не (логическое отрицание), унарный плюс, унарный минус
*, /, % умножение, деление, модуль
+, - сложение, вычитание
.. оператор диапазона
<, <=, >=, > меньше, меньше, меньше, больше, больше, чем
IN, NOT IN
==, !=, LIKE, NOT LIKE, =~, !~
AT LEAST
OUTBOUND, INBOUND, ANY, ALL, NONE
&&, AND логическое И
OR логическое ИЛИ
INTO
WITH
=
?, :
DISTINCT
,

Круглые скобки ( и ) могут использоваться для обеспечения другого порядка оценки оператора.

Комментарии