RQL-выражения для работы с объектами доменов
В данном разделе описано, как использовать язык RQL в политиках доступа и правилах данных схем доменов. Описано создание RQL-выражений, которые включают получение данных, фильтрацию и обогащение, а также управление выводом данных.
|
В данном разделе при описании RQL-выражений приняты следующие соглашения:
|
Синтаксис RQL-выражений
Описанный в этом разделе синтаксис RQL-выражений используется для описания условий в политиках доступа, а также в правилах данных схем доменов. В правилах данных RQL-выражения используются в блоках rql:
-
для описания условий срабатывания правил;
-
для вычисления значений при эффектах
defaultиallowed; -
для валидации данных при эффекте
allowed.
В RQL не указывается имя таблицы, так как контекст выполнения всегда задается текущим доменом:
SELECT
field_name [AS alias_name],
field_name_2 [AS alias_name_2],
[with(@subquery_alias, select(<expression>))],
[from('domain.id', @source_id, @source_alias)],
[join('domain.id', @source_id, @source_alias, on(eq(<expression>)))]
[(INNER | LEFT | RIGHT | FULL) JOIN other_entity_name [AS join_alias_name]
ON <expression>]
[WHERE <expression>]
[ORDER BY field_name [ASC | DESC]]
[LIMIT <m> [OFFSET <n>]]
| RQL | SQL | Комментарий |
|---|---|---|
|
|
Указывать имя таблицы не нужно. В RQL-выражении можно вызывать встроенную функцию с аргументами. |
|
|
При фильтрации оператор |
|
|
Используется системный псевдоним |
|
|
Используются системные псевдонимы |
|
|
Используется системный псевдоним |
|
|
Используется системный псевдоним |
|
|
Проверка нахождения вне диапазона. |
|
|
Для создания массива используется функция |
|
|
Использование функции соединения. |
Обращение к сущностям и связям
Обращение к атрибутам сущностей
Чтобы обратиться к атрибуту сущности, используйте один из следующих способов:
-
Указание только названия поля. При обращении к полям таблицы без указания ее названия система автоматически начинает поиск поля только в основной сущности.
Синтаксис<field_id>
Рекомендуется использовать данный способ, только если в выражении используется лишь одна сущность. ПримерУсловие выполняется, если значение поле
loginтекущей сущностиUserравноsome_name. Условие можно записать так:condition: !rql login = 'some_name' -
Указание идентификатора сущности и названия поля.
Синтаксис@<entity_id>.<field_id>
Обращения вида
@<entity_id>.<field_id>допустимы только в следующих случаях:Для текущей сущности можно использовать специальный псевдоним
@doc.Примеры-
Сущность
Categoryприсоединена конструкцией видаJOIN Category. К полюnameсущностиCategoryможно обратиться так:@Category.name. -
Условие выполняется, если значение поле
usernameтекущей сущностиSystemUserравноsome_name. Условие можно записать так:condition: !rql @doc.username = 'some_name'
-
-
Указание псевдонима сущности и названия поля.
Синтаксис@<entity_alias>.<field_id>
ПримерыСущность
Categoryприсоединена конструкцией видаJOIN Category AS cat. К полюnameсущностиCategoryможно обратиться так:cat.name.
Здесь:
-
<entity_id>— идентификатор сущности из схемы домена; -
<field_id>— идентификатор атрибута сущности из схемы домена; -
<entity_alias>— псевдоним сущности, заданный в RQL-выражении конструкциейAS …
Обращение к элементам массива
Индексы элементов массива указываются в квадратных скобках. Нумерация элементов массива начинается с 1. Таким образом, в массиве из n элементов первый элемент имеет индекс array[1], а последний — array[n].
constraint: !rql relatives IS NULL OR (@doc.relatives[1] LIKE '%строка'
AND CAST(@doc.relatives[2], 'INTEGER') = 42)
Данное RQL-выражение задает ограничение для атрибута relatives:
-
Если значение атрибута отсутствует (
NULL), ограничение считается выполненным. -
В противном случае:
-
Из массива
relativesберется первый элемент и проверяется, что его строковое значение оканчивается на подстроку "строка". -
Из того же массива берется второй элемент, приводится к типу
INTEGERи сравнивается с числом 42.
-
Таким образом, атрибут relatives либо не должен быть задан, либо должен содержать массив, в котором первый и второй элементы удовлетворяют указанным условиям.
Обращение к атрибутам таблицы
Обращаться к столбцам таблицы в текущей строке можно с помощью псевдонима @row:
@row.<table_field>
Здесь <table_field> — идентификатор атрибута внутри атрибута-таблицы в схеме домена.
Извлечение компонентов значений
Получить значение поля из метаданных атрибута типа Файл (Attachment) можно с помощью функции extract(), например:
extract(@doc.attachment, 'filename')
С помощью этого выражения мы извлекаем имя файла из атрибута attachment текущего объекта.
Извлечь компоненты из даты и времени можно с помощью функции DATE_PART(), например:
DATE_PART('hour', @CurrentTimestamp)
В этом выражении мы извлекаем значение часа из текущей метки времени.
Обращение к связи
Чтобы обратиться к связи, используйте ее псевдоним @<linkage_alias>, заданный одним из следующих способов:
В рамках связи можно обратиться:
-
К сторонам связи:
@<linkage_alias>.<sideN>. -
К атрибутам связи, в том числе системным:
@<linkage_alias>.<field_id>.
Здесь:
-
<linkage_alias>— псевдоним связи, заданный в RQL-выражении; -
<field_id>— идентификатор атрибута сущности из схемы домена; -
<sideN>— сторона связи:-
side1— сторона 1; -
side2— сторона 2.
-
SELECT @links.side2, from('current', @linkages_allattributes, @links) WHERE @links.side1 = @doc.id
В этом примере связь linkages_allattributes в текущем домене указывается как источник данных с псевдонимом links. Затем применяется фильтрация по стороне 1 связи и выбирается сторона 2.
Указание возвращаемых полей (оператор SELECT)
Контекстом выполнения RQL-выражений являются объекты сущностей и связей, для которых в схеме домена определена структура данных в виде атрибутов.
Оператор SELECT используется для указания определенных полей, которые будут включены в результат RQL-выражения. Имена полей отделяются друг от друга запятыми.
SELECT <expression>[, <expression>]
| Не ставьте разделитель после последнего поля, включенного в выражение. |
Если в RQL-выражении нет оператора SELECT или указана конструкция SELECT *, то оно вернет все атрибуты, описанные для сущности в схеме домена. Поэтому, если не требуется четкое определение формата данных, оператор SELECT может опускаться.
expression: !rql SELECT 'заданное имя' AS defaultName
В данном RQL-выражении задается значение по умолчанию для атрибута defaultName — "заданное имя".
В случаях, когда в выражении нужно использовать промежуточные вычисления, используйте функцию SELECT().
|
Формирование массивов
Массивы в выражениях используются для формирования списков значений. Массив можно задать одним из двух способов:
-
Перечисление значений в квадратных скобках. Этот способ подходит для конструкции с
SELECT, если массив состоит из чисел или строк:Выборка массива чиселSELECT [1, 2, 3, 4] as items -
Создание массива через функцию
ARRAY(). Этот способ используется:
Примеры
attr IN SELECT(UNNEST(ARRAY(users.name, @CurrentUser.id)))
В данном случае для использования элементов массива в выборке используется функция UNNEST().
expression: !rql SELECT ARRAY(@enumIocTypes.Account, @enumIocTypes.File)
В данном выражении используется ссылка на перечисление, описанное в схеме домена.
expression: !rql SELECT ARRAY(TSRANGE('2025-04-01', '2025-05-01'), TSRANGE('2025-10-01', '2025-11-01'))
В данном выражении используется ссылка на перечисление, описанное в схеме домена.
Использование псевдонимов (оператор AS)
При описании формата результата могут использоваться различные выражения, включая арифметические операции и встроенные функции. Чтобы использовать результат такого выражения, ему нужно присвоить псевдоним:
LENGTH()SELECT LENGTH(someString) AS len
Ознакомьтесь с описанием псевдонимов.
Указание источников данных (from())
Функция from() используется совместно с оператором SELECT и позволяет выполнять выборку из указанной сущности или связи.
from(['<domain_id>', ]@<source_id>[, <source_alias>])
Здесь:
-
<domain_id>— идентификатор домена. По умолчанию — текущий домен.Для обращения к текущему домену можно использовать псевдоним 'current'. -
<source_id>— идентификатор сущности или связи. -
<source_alias>— псевдоним сущности или связи для использования в условиях. По умолчанию принимает значение имени сущности или связи.
SELECT
@links.side2,
from('current', @linkages_allattributes, @links)
WHERE @links.side1 = @doc.id
ORDER BY @links.side1 DESC
LIMIT 1
В данном примере:
-
Происходит выборка из связи
linkages_allattributesв текущем домене. Выборке присваивается псевдоним@links. -
Выборка фильтруется по значению стороны 1 — выбираются экземпляры связи, в которых на этой стороне находится текущий объект.
-
Результат сортируется по стороне 1 в порядке возрастания.
-
Результат ограничивается одной записью.
-
Запрос возвращает значение стороны 2 в результате.
Соединение данных из нескольких сущностей (оператор и функции JOIN)
Данные из нескольких сущностей можно объединять и фильтровать с помощью оператора JOIN и функций объединения. Записи можно фильтровать по наличию связи с определенной сущностью, а также по значениям атрибутов связанной сущности.
Ознакомьтесь с описанием оператора JOIN.
Использование условий (оператор WHERE)
При использовании RQL-выражений для фильтрации данных оператор WHERE можно не указывать.
При использовании проекций оператор WHERE позволяет применять к указанным полям выборку по определенному условию.
SELECT <expression> WHERE <expression>
SELECT organizationId WHERE length(organizationId) = 5
Это RQL-выражение возвращает события с количеством символов в поле organizationId, равным 5.
В условиях используются операторы сравнения, работы с множествами и проверки на пустое значение. Ознакомьтесь с описанием условий.
Сортировка возвращаемых результатов (оператор ORDER BY)
Результаты запроса можно сортировать по любому полю с помощью оператора ORDER BY.
Направление сортировки задается модификаторами:
-
ASC— по возрастанию; -
DESC— по убыванию.
[SELECT <expression>]
ORDER BY
<field_name_1> [ASC | DESC],
<field_name_2> [ASC | DESC],
...,
<field_name_N> [ASC | DESC]
Здесь:
-
<field_name_1> … <field_name_N>— имена полей, по которым нужно отсортировать результаты.
ORDER BY collectorId
Это выражение возвращает записи с сортировкой по полю collectorId в порядке возрастания.
Максимальное количество и пропуск возвращаемых записей (операторы LIMIT и OFFSET)
Вы можете ограничить количество возвращаемых записей с помощью оператора LIMIT.
Также можно добавить команду OFFSET, которая указывает, сколько строк необходимо пропустить перед началом вывода. Это полезно, если вы хотите начать вывод данных с определенной строки.
LIMIT <m> [OFFSET <n>]
Здесь:
-
<m>— число записей, до которого нужно сократить выборку; -
<n>— число пропускаемых записей.
Пример
LIMIT 20
Это выражение ограничивает выборку 20 записями.
LIMIT 20 OFFSET 10
Это выражение позволяет пропустить первые 10 строк и вывести следующие 20.
Рекомендуется использовать команду OFFSET только при необходимости, особенно с большими значениями пропуска, так как это снижает производительность.
|
Функции, вложенные запросы и CTE
В RQL поддерживаются функции, а также вложенные запросы и общие табличные выражения (CTE). Результат их выполнения используется в местах вызова.
Вложенные запросы и общие табличные выражения задаются с помощью специальных функций with() и SELECT(). Внутри таких выражений применяются конструкции для управления выборкой в виде функций. Они аналогичны одноименным операторам в основном запросе.
Ознакомьтесь с подробным описанием в разделах:
Примеры использования RQL-выражений в правилах данных
Скрытие атрибута при отсутствии связей
dataRules:
- id: dataR_hidden_table
name: Attribute hidden
description: К атрибуту tableAttr применяется эффект hidden, если для текущего объекта отсутствуют экземпляры связи some_linkage.
target: entity
entity: SomeEntity
condition: !rql |
SELECT(count(id), FROM('current', @linkage_vulnerability, @link), WHERE(eq(@link.side1, @doc.id))) = 0
rule:
effect: hidden
attributes:
- attribute: tableAttr
В данном примере запрос используется для определения видимости атрибута:
-
Выполняется выборка из связи
linkage_vulnerabilityв текущем домене. -
Экземпляры фильтруются по соответствию стороны 1 идентификатору текущего объекта.
-
Используется агрегатная функция
count()для подсчета количества экземпляров в связиlinkage_vulnerability. -
Количество экземпляров сравнивается с нулем.
-
Если результат равен нулю, атрибут
tableAttrне отображается в представлениях объекта.
Таким образом, если объект не связан с уязвимостью, атрибут-таблица не отображается.
Условная обязательность атрибута
dataRules:
- id: dataR_required_table
name: Entity required
description: К атрибуту someAttr применяется эффект required, если у объекта присутствуют определенные связи.
target: entity
entity: SomeEntity
condition: !rql |
SELECT(count(id), FROM('current', @some_linkage, @link), WHERE(eq(@link.side1, @doc.id))) > 0
rule:
effect: required
attributes:
- attribute: someAttr
В данном примере запрос используется для определения обязательности атрибута:
-
Выполняется выборка из связи
some_linkageв текущем домене. -
Экземпляры фильтруются по соответствию стороны 1 идентификатору текущего объекта.
-
Используется агрегатная функция
count()для подсчета количества экземпляров в связиsome_linkage. -
Количество экземпляров сравнивается с нулем.
-
Если результат больше нуля, атрибут
someAttrстановится обязательным для заполнения.
Для обратной логики — сделать атрибут обязательным, если связи нет, используется оператор = 0:
dataRules:
- id: dataR_required_table
name: Entity required
description: К атрибуту someAttr применяется эффект required, если у объекта присутствуют определенные связи.
target: entity
entity: SomeEntity
condition: !rql |
SELECT(count(id), FROM('current', @some_linkage, @link), WHERE(eq(@link.side1, @doc.id))) = 0
rule:
effect: required
attributes:
- attribute: someAttr
Динамическая фильтрация справочника
dataRules:
- id: dataR_allowed_table
name: Entity allowed
description: Применение эффекта allowed к атрибуту city_id на основе выбранного значения country_id.
target: entity
entity: SomeEntity
condition: !rql |
country_id IS NOT NULL
rule:
effect: allowed
attributes:
# Атрибут типа Reference.
- attribute: city_id
expression: !rql |
SELECT @city.id AS 'city_id', @city.name AS 'name', FROM('dictionaries.example.com', @cities, @city) WHERE @city.country_id = @doc.country_id ORDER BY @city.name ASC
constraint: !rql |
city_id IN SELECT(@city.id, FROM('dictionaries.example.com', @cities, @city), WHERE(eq(@city.country_id, @doc.country_id)))
Данное правило реализует зависимость между двумя атрибутами:
-
Условие: правило применяется только после заполнения атрибута
country_id. -
Выражение: формирует динамический список значений из внешнего домена
dictionaries.example.com, фильтруя их по значениюcountry_idв текущем объекте. -
Ограничение: выполняет валидацию, гарантируя, что указанное пользователем значение действительно принадлежит к списку.
Таким образом, после указания страны пользователь может выбирать только города этой страны.
Фильтрация по атрибуту связанной сущности
dataRules:
- id: dataR_required_table
name: Entity required example
description: Установление обязательности поля в зависимости от атрибутов связанного объекта.
target: entity
entity: SomeEntity
condition: !rql |
SELECT join('current', @some_linkage, @link, ON(eq(@link.side1, @doc.id))), join('current', @incidents, @incident, ON(eq(@link.side2, @incident.id))) WHERE @incident.weight > 100
rule:
effect: required
attributes:
- attribute: someAttr
В данном примере используется цепочка соединений через функции join():
-
Первое соединение связывает экземпляры связи
some_linkageс текущим объектом. Соединение определяется равенством стороны 1 связи и идентификатора текущего объекта. -
Второе соединение связывает сторону 2 связи с сущностью
incident. -
Фильтрация проверяет атрибут
weightсвязанной сущностиincidents. -
Атрибут
someAttrстановится обязательным, если найден хотя бы один связанный инцидент с весом больше 100.
Фильтрация по атрибуту связи
dataRules:
- id: dataR_required_link_attr
name: Entity required example
description: Установление обязательности поля в зависимости от атрибута связи.
target: entity
entity: SomeEntity
condition: !rql |
SELECT join('current', @some_linkage, @link, ON(eq(@link.side1, @doc.id))) WHERE @link.weight > 100
rule:
effect: required
attributes:
- attribute: someAttr
В данном примере проверяется значение атрибутов самой связи:
-
Соединение связывает экземпляры связи
some_linkageс текущим объектом. Соединение определяется равенством стороны 1 связи и идентификатора текущего объекта. -
Фильтрация проверяет атрибут
weightсвязи. -
Атрибут
someAttrстановится обязательным, если вес связи больше 100.
Фильтрация по значению атрибута объекта по ссылке
dataRules:
- id: dataR_allowed_user
name: Entity allowed
description: Применение эффекта allowed к атрибуту user_id в зависимости от значения объекта по ссылке.
target: entity
entity: Incident
condition: true
rule:
effect: allowed
attributes:
# Атрибут типа Reference.
- attribute: responsible_user_id
expression: !rql |
SELECT @user.id AS user_id, @user.name AS name, FROM('users.example.com', @users, @user) WHERE @user.isActive = true ORDER BY @user.name ASC
constraint: !rql |
responsible_user_id IN SELECT(@user.id, FROM('users.example.com', @users, @user), WHERE(@user.isActive))
В данном примере предполагается, что существует домен users.example.com с сущностью user.
|
Пример работы с атрибутом типа Референс (Reference):
-
Производится выборка из домена
users.example.com. -
В списке доступных значений атрибута
responsible_user_idдопускаются идентификаторы объектовuser, у которых атрибутisActiveравенtrue. -
При валидации проверяется, что значение
responsible_user_idотносится к тому же списку допустимых идентификаторов.
Таким образом, ответственным за инцидент можно назначить только пользователя с активной учетной записью.
dataRules:
- id: dataR_allowed_software
name: Entity allowed
description: Фильтрация справочника ПО, позволяющая выбирать только записи с типом Системное.
target: entity
entity: OperationalSystem
condition: true
rule:
effect: allowed
attributes:
# Атрибут типа Reference.
- attribute: software_id
expression: !rql |
SELECT @software.id AS software_id, @software.name AS name, FROM('dictionaries.example.com', @software) WHERE @software.type = 'Системное' ORDER BY @software.name ASC
constraint: !rql |
software_id IN SELECT(@software.id, FROM('dictionaries.example.com', @software), WHERE(eq(@software.type, 'Системное')))
Здесь фильтрация справочника выполняется по заданному строковому значению атрибута type. Таким образом, при создании сущности "Операционная система" можно создать ссылку software_id только на ПО с типом "Системное".
Запрет изменения значения в зависимости от наличия связей
dataRules:
- id: dataR_status_restriction
name: Entity allowed example
description: Ограничение возможности изменения атрибута.
target: entity
entity: Incident
condition: !rql |
SELECT(count(id), FROM('current', @assignies, @assignee_link), WHERE(eq(@assignee_link.side1, @doc.id))) = 0
rule:
effect: allowed
attributes:
- attribute: status
constraint: !rql |
status != 'Закрыт'
В данном примере эффект allowed используется для валидации значения атрибута:
-
Вложенный запрос проверяет количество экземпляров связи
assigniesдля текущего объекта. -
Если связей нет, применяется ограничение: значение атрибута
statusне должно быть равно "Закрыт".
Таким образом, инцидент нельзя закрыть, если не назначен ответственный.
Была ли полезна эта страница?