Соединение данных из нескольких сущностей в RQL-выражениях при настройке правил

В данном разделе описано соединение и фильтрация данных из разных сущностей при настройке правил данных и политик доступа.

В данном разделе при описании RQL-выражений приняты следующие соглашения:

  • Необязательные компоненты выражений заключаются в квадратные скобки.

  • Под обозначением <expression> понимается выражение, то есть применение оператора, функция, идентификатор, литерал, арифметическое выражение или выражение в скобках.

  • Имена функций и операторов RQL могут использоваться как в верхнем, так и в нижнем регистре. В этом разделе имена функций приведены в верхнем регистре, если они являются обертками или имеют прямой аналог среди нативных функций SQL.

Есть два способа соединить данные:

Использование оператора JOIN

Оператор JOIN служит для фильтрации и обогащения записей на основе данных из связанных сущностей, которые относятся к одному домен:

  • Для фильтрации по данным из связанных сущностей используются операции INNER JOIN и LEFT JOIN. Записи можно фильтровать по наличию связи с определенной сущностью, а также по значениям атрибутов связанной сущности.

    Пример
    Выполняется JOIN к сущности Город и задается условие AND city.name = 'Самара'.
  • Для обогащения информации данными из связанных сущностей используются операции INNER JOIN, LEFT JOIN, RIGHT JOIN и FULL JOIN. В компоненте SELECT можно указать атрибуты связанной сущности.

    Пример
    Выполняется JOIN к сущности Город и в SELECT добавляется название города с помощью конструкции вида SELECT …​, city.name AS "cityName".

При этом данные основной и связанной сущностей анализируются как данные в двух разных таблицах: данные основной сущности используются как левая таблица, а данные связанной — как правая таблица.

Синтаксис
[SELECT ...] (INNER | LEFT | RIGHT | FULL) JOIN <other_entity_name> [AS alias_name] ON <expression>

Здесь:

  • (INNER | LEFT | RIGHT | FULL) определяет тип операции JOIN, применяемой для объединения данных из левой и правой таблиц:

    • INNER JOIN выбирает строки, где присутствует совпадение по заданным условиям в обеих таблицах.

    • LEFT JOIN отображает все строки из левой таблицы, дополняя их данными из правой таблицы при наличии совпадений.

    • RIGHT JOIN аналогичен LEFT JOIN, но выводит все строки из правой таблицы, дополняя их данными из левой таблицы при наличии совпадений.

    • FULL JOIN объединяет методы LEFT JOIN и RIGHT JOIN, показывая все строки из обеих таблиц.

  • <other_entity_name> обозначает имя связанной сущности, которая используется как правая таблица для операции JOIN.

  • AS alias_name предоставляет возможность задать псевдоним для связанной сущности.

    Рекомендуется всегда явно задавать псевдоним при соединении — это упростит дальнейшее обращение к данным в RQL-выражении.
  • <expression> формулирует условие объединения, используя операции сравнения и логические операторы, чтобы определить совпадения данных между таблицами.

    Обратиться к полю сущности можно одним из следующих способов:

    • Для текущей сущности — указать только название поля: <field_id>.

    • Для присоединенных сущностей — указать идентификатор сущности и название поля: @<entity_id>.<field_id>.

    • Указать псевдоним сущности и название поля: <entity_alias>.<field_id>. Псевдоним должен быть объявлен через AS …​, для текущей сущности можно использовать псевдоним @doc.

    Ознакомьтесь с описанием обращения к полям.

Пример использования оператора JOIN

condition: !rql |
  INNER JOIN @Person as @Person ON @doc.deviceOwner = @Person.id WHERE @doc.deviceStatus = @deviceStatus.waiting AND @Person.city = 'Москва'

В данном условии:

  • Выполняется соединение с сущностью Персона (Person) под псевдонимом @Person.

  • Устройство считается связанным с персоной, если его владелец (deviceOwner) совпадает с идентификатором персоны (id). В выборку попадают только объекты, где есть совпадение в обеих таблицах.

  • Производится фильтрация по атрибутам как основной, так и связанной сущности:

    • Выборка ограничивается объектами с атрибутом deviceStatus, равным значению с идентификатором waiting из перечисления deviceStatus.

    • Выборка ограничивается персонами из города Москва.

Использование функций для соединения данных

В RQL, помимо синтаксиса с операторами JOIN, существуют следующие функции для работы с соединениями:

  • join(), innerJoin() — аналог INNER JOIN;

  • leftJoin() — аналог LEFT JOIN;

  • rightJoin() — аналог RIGHT JOIN;

  • fullJoin() — аналог FULL JOIN.

Эти функции используются для описания соединений, включая сценарии с сущностями из разных доменов. Функции соединения размещаются внутри компонента SELECT, вложенных запросов и общих табличных выражений, но не добавляют полей в результат. Их задача — описать связи между сущностями, на основе которых формируется соединение. Псевдонимы, созданные внутри функций соединения, можно использовать:

  • в условии WHERE для фильтрации;

  • в компоненте SELECT для выбора атрибутов связанных сущностей.

Синтаксис соединения с сущностью или связью
SELECT <join>('<domain_id>', @<id>, [@<alias>], on(<condition>))
Синтаксис соединения с результатом CTE
SELECT with(@<cte_alias>, select(<expression>)), <join>(@<cte_alias>, on(<condition>)).

Здесь:

  • <join> — конкретная функция соединения;

  • <domain_id> — идентификатор домена. Обязателен при присоединении сущности или связь.

    Для обращения к текущему домену можно использовать псевдоним 'current'.
  • <id> — идентификатор сущности или связи. Указывается с префиксом @.

  • <alias> (необязательный аргумент) — псевдоним сущности. Если не указан, в качестве псевдонима используется <id>.

  • <cte_alias> — псевдоним общего табличного выражения, созданного ранее через функцию with(). Если первым аргументом функции соединения указан псевдоним без указания домена, соединение выполняется с соответствующим табличным выражением.

  • <condition> — условие связывания сущностей.

Описание условий соединения (функция on())

Функция on() используется исключительно внутри функций соединения и определяет условия соединения сущностей. Внутри on() можно указывать одиночное условие равенства или набор условий, объединенных логическими операциями.

Примеры

Условие равенства
on(eq(@doc.catOwner, @p.id))

Условия объединяются с помощью функций:

  • and() — логическое И,

  • or() — логическое ИЛИ.

Пример объединения условий
on(and(eq(@doc.catOwner, @p.id),or(eq(@doc.createdBy, @p.userId),eq(@doc.assignedTo, @p.id))))

Примеры использования функций соединения

Пример 1. Использование rightJoin()

condition: !rql |
  SELECT rightJoin(@Person, on(eq(@doc.catOwner, @Person.id))) WHERE @Person.city = 'Москва'

В данном условии:

  • Выполняется соединение с сущностью Персона (Person).

  • Объект считается связанным с персоной, если его владелец (catOwner) совпадает с идентификатором персоны (id). В выборку попадают все записи сущности Персона; данные из основной сущности (@doc) подставляются, только если найдено соответствие по условию.

  • Выборка ограничивается персонами из города Москва.

Пример 2. Использование leftJoin()

condition: !rql |
  SELECT leftJoin(@Person, @p, on(eq(@doc.catOwner, @p.id))) WHERE @p.city = 'Москва'

В данном условии:

  • Выполняется соединение с сущностью Персона (Person) под псевдонимом @p.

  • Объект считается связанным с персоной, если владелец (catOwner) совпадает с идентификатором персоны (id). В выборку попадают все записи основной сущности; данные из основной сущности Персона подставляются, только если найдено соответствие по условию.

  • Выборка ограничивается персонами из города Москва.

Пример 3. Использование innerJoin()

condition: !rql |
  SELECT innerJoin('persons.example.com', @Person, @p, on(and(eq(@doc.catOwner, @p.id), or(eq(@doc.createdBy, @p.id), eq(@doc.assignedTo, @p.id))))) WHERE @p.city = 'Москва' AND @doc.catPosition = @WorkPosition.junior

В данном условии:

  • Выполняется соединение с сущностью Персона (Person) под псевдонимом @p.

  • Объект считается связанным с персоной, если выполняются оба условия:

    • Значение атрибута владельца (catOwner) совпадает с идентификатором персоны (id).

    • Объект был создан пользователем (createdBy) или назначен пользователю (assignedTo), совпадающему с идентификатором персоны.

      В выборку попадают только объекты, где есть совпадение в обеих таблицах.

  • Выборка ограничивается объектами с атрибутом catPosition, равным значению junior из перечисления WorkPosition, и персонами из города Москва.

Была ли полезна эта страница?

Обратная связь