Строковые выражения#
Введение#
В DataSpace можно использовать строковые выражения, которые позволяют моделировать выражения различных уровней сложности.
Поддерживаются следующие типы строковых выражений:
примитивное выражение;
коллекция примитивных выражений;
сущность;
коллекция сущностей;
условие.
Базовые объекты#
В грамматике строковых выражений предусмотрены следующие базовые объекты:
Корневая сущность#
Корневая сущность имеет тип сущность, обозначается с помощью ключевого слова root и имеет настройку
спецификацииtype (тип сущности) — позволяет уточнить тип сущности для обращения к свойствам типа-потомка.
Корневую сущность можно, например, использовать для обращения к искомой сущности при поиске.
Пример 1
Условие: код продукта соответствует шаблону product% (при поиске продуктов).
root.code $like 'product%'
Пример 2
Примитивное значение: ставка депозита больше 10 (при поиске продуктов).
root{type = Deposit}.rate > 10
Примечание
Рекомендуется для обращения к корневой сущности использовать текущий элемент в ситуациях, когда в контексте они обозначают один и тот же объект.
Элемент коллекции#
Элемент коллекции имеет тип сущность или примитивное выражение в зависимости от контекста. Обозначается с помощью
ключевого слова elem. В случае, если элемент имеет тип сущность, то у него присутствует настройка спецификации type
(тип сущности) — позволяет уточнить тип сущности-элемента для обращения к свойствам типа-потомка.
Элемент коллекции можно использовать в поисках для обращения к элементу коллекции при фильтрации коллекции.
Пример 1
Условие: код сервиса начинается с кода продукта (при запросе сервисов при поиске продуктов).
elem.code $like root.code + '%'
Пример 2
Условие: состояние начинается с символа 'a' (при запросе состояний при поиске продуктов).
elem $like 'a%'
Примечание
Рекомендуется для обращения к элементу коллекции использовать текущий элемент.
Текущий элемент#
Текущий элемент имеет тип сущность или примитивное значение в зависимости от контекста. Обозначается с помощью
ключевого слова it. Если элемент имеет тип сущность, то у него присутствует настройка спецификации type (тип сущности) — позволяет уточнить тип сущности-элемента для обращения к свойствам типа-потомка.
Текущий элемент используется для обращения к текущему рассматриваемому элементу выражения. Например, в случае условия поиска текущий элемент является эквивалентом корневой сущности, а в случае фильтрации коллекции — элемента коллекции.
Пример 1
Условие: код продукта соответствует шаблону 'product%' (при поиске продуктов).
it.code $like 'product%'
Пример 2
Условие: код сервиса начинается с кода продукта (при запросе сервисов при поиске продуктов).
it.code $like root.code + '%'
Сущность под псевдонимом#
Если в контексте присутствуют сущности под псевдонимом, то к ним можно обратиться через ключевое слово @ с последующим указанием псевдонима.
При обращении к сущности под псевдонимом можно использовать настройку спецификации type — тип сущности. Параметр позволяет уточнить тип сущности для обращения к свойствам типа-потомка.
Пример
Условие: код продукта под псевдонимом 'product' равен 'product1' (при запросе сервисов у запрошенных продуктов при поиске документов).
@product.code == 'product1'
Сущности#
Сущности имеют тип коллекция сущностей, обозначаются с помощью ключевого слова entities и имеют следующие настройки
спецификации:
type— тип сущностей (обязательная настройка);elemAlias— псевдоним элемента;cond— условие фильтрации сущностей.
Пример
Условие: существуют контракты, код которых равен коду продукта (при поиске продуктов).
entities{type = Contract, cond = it.code == root.code}.$exists
Примитивное значение#
Имеется возможность задать базовые примитивные выражения:
Тип |
Формат |
Пример значения |
|---|---|---|
Строка |
Строка, обрамленная одинарными кавычками ( |
|
Целое число |
|
|
Вещественное число |
Целая и вещественная часть отделены точкой. Использование экспоненциальной записи не допускается |
|
Дата |
ISO 8601 с префиксом |
|
Дата и время |
ISO 8601 с префиксом |
|
Дата и время со смещением |
ISO 8601 с префиксом |
|
Время |
ISO 8601 с префиксом |
|
Логическое значение |
|
Текущая метка времени#
Лексема now представляет текущее время БД (с учетом часового пояса).
Пример
Коллекция сущностей: заблокированные прикладной блокировкой продукты.
entities{type = Product, cond = it.syalUnlockTime >= now}
Спецификация#
Некоторые объекты могут иметь дополнительные настройки (например, type для корневой сущности).
Для задания данных настроек вводится понятие спецификации.
Спецификацию для объекта можно указать в фигурных скобках ({ и }), а настройки указываются следующим образом и перечисляются через запятую:
${наименование настройки} = ${значение настройки}`
Пример
Коллекция сущностей: продукты, код которых соответствует шаблону 'product%'.
entities{type = Product, cond = it.code $like 'product%'}
Методы выражений#
Каждый тип выражения предоставляет набор методов, которые можно использовать при описании выражения.
Методы примитивных выражений#
Для примитивных выражений доступны следующие методы:
отрицание:
-${примитивное выражение}(например,-it.number);приведение в верхний регистр:
${примитивное выражение}.$upper(например,it.string.$upper);приведение в нижний регистр:
${примитивное выражение}.$lower(например,it.string.$lower);длина:
${примитивное выражение}.$length(например,it.string.$length);отсечение пробельных символов в начале и конце:
${примитивное выражение}.$trim(например,it.string.$trim);отсечение пробельных символов в начале:
${примитивное выражение}.$ltrim(например,it.string.$ltrim);отсечение пробельных символов в конце:
${примитивное выражение}.$rtrim(например,it.string.$rtrim);округление:
${примитивное выражение}.$round(например,it.number.$round);округление вверх:
${примитивное выражение}.$ceil(например,it.number.$ceil);округление вниз:
${примитивное выражение}.$floor(например,it.number.$floor);хеш:
${примитивное выражение}.$hash(например,it.string.$hash);приведение к строке:
${примитивное выражение}.$asString(например,it.number.$asString);приведение к большому десятичному числу:
${примитивное выражение}.$asBigDecimal(например,it.string.$asBigDecimal);приведение к дате:
${примитивное выражение}.$asDate(например,it.string.$asDate);приведение к дате и времени:
${примитивное выражение}.$asDateTime(например,it.string.$asDateTime);приведение к дате и времени со смещением:
${примитивное выражение}.$asOffsetDateTime(например,it.string.$asOffsetDateTime);приведение ко времени:
${примитивное выражение}.$asTime(например,it.string.$asTime);год:
${примитивное выражение}.$year(например,it.offsetDateTime.$year);месяц:
${примитивное выражение}.$month(например,it.offsetDateTime.$month);день:
${примитивное выражение}.$day(например,it.offsetDateTime.$day);час:
${примитивное выражение}.$hour(например,it.offsetDateTime.$hour);минута:
${примитивное выражение}.$minute(например,it.offsetDateTime.$minute);секунда:
${примитивное выражение}.$second(например,it.offsetDateTime.$second);час смещения:
${примитивное выражение}.$offsetHour(например,it.offsetDateTime.$offsetHour);минута смещения:
${примитивное выражение}.$offsetMinute(например,it.offsetDateTime.$offsetMinute);дата:
${примитивное выражение}.$date(например,it.offsetDateTime.$date);время:
${примитивное выражение}.$time(например,it.offsetDateTime.$time);смещение:
${примитивное выражение}.$offset(например,it.offsetDateTime.$offset);модуль числа:
${примитивное выражение}.$abs(например,it.number.$abs);побитовое отрицание:
~${примитивное выражение}(например,~it.number);побитовое "И":
${примитивное выражение} & ${примитивное выражение}(например,it.number & 4);побитовое "Или":
${примитивное выражение} | ${примитивное выражение}(например,it.number | 4);побитовое "Исключающее или":
${примитивное выражение} ^ ${примитивное выражение}(например,it.number ^ 4);сдвиг влево:
${примитивное выражение} << ${примитивное выражение}(например,it.number << 4);сдвиг вправо:
${примитивное выражение} >> ${примитивное выражение}(например,it.number >> 4);сложение:
${примитивное выражение} + ${примитивное выражение}(например,it.number + 4);разность:
${примитивное выражение} − ${примитивное выражение}(например,it.number − 4);произведение:
${примитивное выражение} * ${примитивное выражение}(например,it.number * 4);деление:
${примитивное выражение} / ${примитивное выражение}(например,it.number / 4);остаток от деления:
${примитивное выражение} % ${примитивное выражение},${примитивное выражение} $mod ${примитивное выражение}(например,it.number % 4,it.number $mod 4);подстрока:
${примитивное выражение}.$substr(${примитивное выражение (индекс начала)})(например,it.string.$substr(4));подстрока:
${примитивное выражение}.$substr(${примитивное выражение (индекс начала)}, ${примитивное выражение (длина)})(например,it.string.$substr(4, it.number));замена:
${примитивное выражение}.$replace(${примитивное выражение (заменяемая строка)}, ${примитивное выражение (новая строка)})(например,it.string.$replace('code', it.name));строка с заполнением слева:
${примитивное выражение}.$lpad(${примитивное выражение}, ${примитивное выражение})(например,it.string.$lpad(10, ' '));строка с заполнением справа:
${примитивное выражение}.$rpad(${примитивное выражение}, ${примитивное выражение})(например,it.string.$rpad(10, ' '));добавление миллисекунд:
${примитивное выражение}.$addMilliseconds(${примитивное выражение})(например,it.date.$addMilliseconds(1));добавление секунд:
${примитивное выражение}.$addSeconds(${примитивное выражение})(например,it.date.$addSeconds(1));добавление минут:
${примитивное выражение}.$addMinutes(${примитивное выражение})(например,it.date.$addMinutes(1));добавление часов:
${примитивное выражение}.$addHours(${примитивное выражение})(например,it.date.$addHours(1));добавление дней:
${примитивное выражение}.$addDays(${примитивное выражение})(например,it.date.$addDays(1));добавление месяцев:
${примитивное выражение}.$addMonths(${примитивное выражение})(например,it.date.$addMonths(1));добавление годов:
${примитивное выражение}.$addYears(${примитивное выражение})(например,it.date.$addYears(1));вычитание миллисекунд:
${примитивное выражение}.$subMilliseconds(${примитивное выражение})(например,it.date.$subMilliseconds(1));вычитание секунд:
${примитивное выражение}.$subSeconds(${примитивное выражение})(например,it.date.$subSeconds(1));вычитание минут:
${примитивное выражение}.$subMinutes(${примитивное выражение})(например,it.date.$subMinutes(1));вычитание часов:
${примитивное выражение}.$subHours(${примитивное выражение})(например,it.date.$subHours(1));вычитание дней:
${примитивное выражение}.$subDays(${примитивное выражение})(например,it.date.$subDays(1));вычитание месяцев:
${примитивное выражение}.$subMonths(${примитивное выражение})(например,it.date.$subMonths(1));вычитание годов:
${примитивное выражение}.$subYears(${примитивное выражение})(например,it.date.$subYears(1));условие "Равен null":
${примитивное выражение} == null(например,it.code == null);условие "Не равен null":
${примитивное выражение} != null(например,it.code != null);условие "Равен":
${примитивное выражение} == ${примитивное выражение}(например,it.code == 'service');условие "Не равен":
${примитивное выражение} != ${примитивное выражение}(например,it.code != 'service');условие "Больше":
${примитивное выражение} > ${примитивное выражение}(например,it.number > 4);условие "Меньше или равно":
${примитивное выражение} <= ${примитивное выражение}(например,it.number <= 4);условие "Меньше":
${примитивное выражение} < ${примитивное выражение}(например,it.number < 4);условие "Подобен":
${примитивное выражение} $like ${примитивное выражение}(например,it.code $like 'service%');условие "Между":
${примитивное выражение} $between (${примитивное выражение}, ${примитивное значение})(например,it.number $between (4, it.number2));условие "В":
${примитивное выражение} $in [${примитивное выражение}, ...](например,it.number $in [4, it.number2, 6]);условие "В":
${примитивное выражение} $in ${коллекция примитивных выражений}(например,it.number $in it.numbers);агрегация "минимум":
${примитивное выражение}.$min(например,it.number.$min);агрегация "максимум":
${примитивное выражение}.$max(например,it.number.$max);агрегация "сумма":
${примитивное выражение}.$sum(например,it.number.$sum);агрегация "среднее":
${примитивное выражение}.$avg(например,it.number.$avg);агрегация "количество":
${примитивное выражение}.$count(например,it.number.$count).
Методы коллекций примитивных выражений#
Для коллекций примитивных выражений доступны следующие методы:
коллекция примитивных выражений на основе преобразования:
${коллекция примитивных выражений}.$map(${примитивное выражение})(например,it.numbers.$map(it $mod root.number).$min)минимум:
${коллекция примитивных выражений}.$min(например,it.numbers.$min);максимум:
${коллекция примитивных выражений}.$max(например,it.numbers.$max);сумма:
${коллекция примитивных выражений}.$sum(например,it.numbers.$sum);среднее:
${коллекция примитивных выражений}.$avg(например,it.numbers.$avg);количество элементов:
${коллекция примитивных выражений}.$count(например,it.numbers.$count);условие "Существует":
${коллекция примитивных выражений}.$exists(например,it.numbers.$exists).
Методы сущностей#
Для сущностей доступны следующие методы:
тип:
${сущность}.$type(например,it.$type);id:
${сущность}.$idлибо${сущность}.id(например,it.$id,it.id);примитив:
${сущность}.${наименование свойства}(например,it.code);коллекция примитивов:
${сущность}.${наименование свойства}${спецификация}(например,it.states,it.states{cond = it $like 'h%'}). Доступная настройка спецификации:cond(условие) — условие фильтрации;ссылка:
${сущность}.${наименование свойства}${спецификация}(например,it.product,it.product{type = Deposit}). Доступные настройки спецификации:type(тип сущности) позволяет уточнить тип сущности для обращения к свойствам типа-потомка;alias(псевдоним) позволяет сохранить ссылку под псевдонимом в контекст;
коллекция ссылок:
${сущность}.${наименование свойства}${спецификация}(например,it.services,it.services{type = SuperService, cond = it.code like root.code + 'service%'},it.services{elemAlias = service, cond = it.parameters{cond = it.code == @service.code}.$exists}.$exists). Доступные настройки спецификации:type(тип сущности) позволяет ограничить коллекцию до коллекции, ссылки которой указывают на сущность указанного типа;elemAlias(псевдоним элемента) позволяет сохранить ссылку из коллекции под псевдонимом в контекст;cond(условие) условие фильтрации;
условие "Равен null":
${сущность} == null(например,it.product == null);условие "Не равен null":
${сущность} != null(например,it.product != null);условие "Существует":
${сущность}.$exists(например,it.product.$exists);условие "Равно":
${сущность} == ${сущность}(например,it.product == it.document.product);условие "Не равно":
${сущность} != ${сущность}(например,it.product != it.document.product);условие "В":
${сущность} $in [${сущность}, ...](например,it.product $in [it.document.product, it.document.relatedProduct]);условие "В":
${сущность} $in ${коллекция сущностей}(например,it.product $in it.services.product).
Методы коллекций сущностей#
Для коллекций сущностей доступны следующие методы:
коллекция примитивных выражений на основе типа сущности:
${коллекция сущностей}.$type(например,it.services.$type);коллекция примитивных выражений на основе id сущности:
${коллекция сущностей}.$idлибо${коллекция сущностей}.id(например,it.services.$id,it.services.id);коллекция примитивных выражений на основе примитива:
${коллекция сущностей}.${наименование свойства}(например,it.services.code);коллекция сущностей на основе ссылки:
${коллекция сущностей}.${наименование свойства}${спецификация}(например,it.services.product,it.services.product{type = Deposit}). Доступная настройка спецификацииtype(тип сущности) позволяет ограничить коллекцию до коллекции, ссылки которой указывают на сущность указанного типа;коллекция примитивных выражений на основе преобразования:
${коллекция сущностей}.$map(${примитивное выражение})(например,it.services.$map(it.operations.$count).$sum)количество элементов:
${коллекция сущностей}.$count(например,it.services.$count);условие "Существует":
${коллекция сущностей}.$exists(например,it.services.$exists).
Методы условий#
Для условий доступны следующие методы:
условие "Отрицание":
!${условие}(например,!it.services.$exists);условие "И":
${условие} && ${условие}(например,it.services.$exists && it.product != null);условие "Или":
${условие} || ${условие}(например,it.services.$exists || it.product != null).
Общие методы#
Доступен общий метод — первый ненулевой элемент: coalesce(${примитивное выражение}, ...) (например, coalesce(it.string, it.string2)).
Приоритеты методов#
Уровень |
Метод |
Описание |
Ассоциативность |
|---|---|---|---|
1 |
|| |
Условие "Или" |
v |
2 |
&& |
Условие "И" |
v |
3 |
! |
Условие "Отрицание" |
|
4 |
| |
Побитовое "Или" |
v |
5 |
^ |
Побитовое "Исключающее или" |
v |
6 |
& |
Побитовое "И" |
v |
7 |
== |
Условие "Равно" |
v |
7 |
!= |
Условие "Не равно" |
v |
8 |
< |
Условие "Меньше" |
|
8 |
>= |
Условие "Больше или равно" |
|
8 |
< |
Условие "Меньше" |
|
8 |
>= |
Условие "Больше или равно" |
|
8 |
$like |
Условие "Подобен" |
|
8 |
$between |
Условие "Между" |
|
8 |
$in |
Условие "В" |
|
9 |
<< |
Сдвиг влево |
|
9 |
>> |
Сдвиг вправо |
|
10 |
+ |
Сложение |
v |
10 |
- |
Разность |
|
11 |
* |
Произведение |
v |
11 |
/ |
Деление |
|
11 |
%, $mod |
Остаток от деления |
|
12 |
- |
Отрицание |
|
12 |
~ |
Побитовое отрицание |
|
13 |
Все остальные методы |
Примеры#
Пример 1
Условие: код продукта равен 'product1' независимо от регистра (при поиске продуктов).
it.code.$lower == 'product1'
Пример 2
Условие: суммарное время выполнение всех сервисов продукта, код которых начинается с кода продукта, не превышает 10 (при поиске продуктов).
it.services{cond = it.code $like root.code + '%'}.executionTime.$sum <= 10