Для объединения данных

Шаги этой группы называются "Соединители". Они служат для объединения записей из потоков с потенциально разными метаданными в соответствии с заданным ключом соединения и способом преобразования.

Соединители имеют как входные, так и выходные порты. Первый входной порт шага-соединителя называется "главным" или "мастером" и обозначается номером «0», остальные входные порты — "подчинённые".

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

HASH_JOIN - объединяет потоки данных из двух и более источников по ключу, не требует предварительной сортировки

MERGE_JOIN - объединяет потоки данных из двух и более источников по ключу, требует предварительную сортировку

CROSS_JOIN - создает декартово произведение записей из подключенных входных портов, не требует предварительной сортировки

HASH_JOIN

HASH_JOIN объединяет потоки данных по ключу.

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

Сначала HASH_JOIN считывает записи из всех подчинённых портов и сохраняет их в хэш-таблицы. Для каждого подчинённого порта создается отдельная хэш-таблица. Размер всех созданных хэш-таблиц не должен превышать размер оперативной памяти сервера, так как хэш-таблицы хранятся в оперативной памяти и ее переполнение приведет к завершению задания с ошибкой. Поэтому имеет смысл в главный входной поток подавать большое количество записей, а в подчинённые потоки – небольшие группы записей.

Затем для каждой записи из мастера производится поиск совпадения с записями из каждой хэш-таблицы по заданному ключу соединения.

Если совпадение найдено, кортеж из записи главного порта и хэш-таблицы подчинённого порта трансформируется заданным образом. Полученная после преобразования запись подаётся на первый выходной порт. Метод преобразования вызывается для каждого кортежа главной и соответствующих подчинённых записей. Записи из главного порта, которые не были объединены подаются на второй выходной порт.

Пример.

Даны два потока записей. В одном потоке содержится информация о названии продукта в поле «Product» и его цвете на русском языке «rus_color», во втором потоке – названию цвета на русском языке соответствует название на английском «eng_color». Задача сопоставить продукт и его цвет на английском языке.

порт0:

productrus_color
шарфкрасный
носокбелый
свитерзеленый

порт1:

rus_coloreng_color
синийblue
желтыйyellow
красныйred

Ключ соединения: joinKey="$rus_color"

Формула для объединения:


<Attr name="transform">
<![CDATA[//#PseudoRust:code
     pub fn transform() -> OutPort {
        output.out_0.Product = input.in_0.Product;
        output.eng_color = input.in_1.eng_color;
        return out_port![ALL]
    }
]]></Attr>

Исходящие записи:

порт0:

producteng_color
шарфred

порт0:

productrus_color
носокбелый
свитерзеленый

Порты HASH_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портЛюбые
1даДополнительный входной порт
2-nнетОпциональные дополнительные входные порты
Output0даИсходящий порт
1нетПорт для записей, которые не подошли по ключу соединенияКак у Input 0

Атрибуты HASH_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, по которому объединяются входящие потоки данных

joinKey="$obj_type#$obj_type=$x_type;lvl"

joinTypeнетТип объединения. Бывает "inner"(по умолчанию) и "leftOuter"joinType="leftOuter"
transformда

Преобразование, определенное в файле задания на внутреннем языке системы1

<attr name="transform"><![CDATA[
    function transform() {
    $out[0].user_code = $in[0].user_id;
    $out[0].bind_code = $in[1].bind_code;
    $out[0].bind_datetime = $in[1].bind_datetime;
            
    return ALL;
    }]]>
</attr>
slaveDuplicatesнетЕсли установлено значение true, разрешены записи с повторяющимися значениями ключей. Если false, для объединения используется только последняя запись. По умолчанию true.slaveDuplicates="false"
1

В данный момент используется псевдораст, в дальнейшем возможен переход на другой язык описания преобразований.

MERGE_JOIN

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

MERGE_JOIN получает данные через два или более входных порта, каждый из которых может иметь различную структуру метаданных. Затем объединенные данные отправляются на первый выходной порт. Необъединенные данные можно вывести на второй выходной порт.

Порты MERGE_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портлюбые
1даВедомый входной порт
2-nнетДополнительные ведомые входные порты
Output0даВыходной порт для объединенных данных
1нетВыходной порт для необъединённых данныхкак на Input 0

Типы полей метаданных на первом входном и втором выходном портах должны быть одинаковыми, имена полей при этом могут отличаться.

Атрибуты MERGE_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
joinKeyдаКлюч, по которому объединяются входящие потоки данных. Представляет собой последовательность выражений сопоставления для всех ведомых портов. Выражения сопоставления отделяются друг от друга хешем #. Каждое из выражений сопоставления представляет собой последовательность имен полей из главной и подчинённой записей, разделенных знаком равно. Выражения внутри joinKey отделяются друг от друга точкой с запятойjoinKey="$name(a);$color(d)#$product;$tint;#$name;$tone"
joinTypeнетТип объединенияinner (по умолчанию) | leftOuter
transformдаПреобразование, определенное в файле задания на внутреннем языке системы
<attr name="transform"><![CDATA[
    function transform() {
        $out[0].id = $in[0].id;
        $out[0].name = $in[0].name;

        return ALL;
    }
    ]]>
</attr>
slaveDuplicatesнетЕсли установлено значение true, разрешены записи с повторяющимися значениями ключей. Если false, для объединения используется только последняя запись. По умолчанию true.slaveDuplicates="false"

CROSS_JOIN

CROSS_JOIN создает декартово произведение записей из подключенных входных портов.

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

CROSS_JOIN автоматически передаёт метаданные на выходной порт в соответствии с метаданными на его входных портах.

Заметка: при обработке очень большого количества записей, на жёстком диске могут быть созданы временные файлы с обрабатываемыми записями. Это предотвращает чрезмерное использование оперативной памяти.

Порты CROSS_JOIN:

Тип портаНомерОбязательныйОписаниеМетаданные
Input0даГлавный входной портлюбые
1-nнетВедомый входной порт(ы)
Output0даДля выходных записей

Атрибуты CROSS_JOIN:

АтрибутОбязательныйОписаниеВозможные значения
transform

нет2

Функция преобразования данных, определённая в графе

<attr name="transform"><![CDATA[
    function transform() {
        $out[0].id = $in[1].id;
        $out[0].name = $in[1].name;
        $out[0].test_data_id = $in[0].test_data_id;
        $out[0].tmstmp = $in[0].tmstmp;
        $out[0].category_id = $in[0].category_id;

        return ALL;
    }
    ]]>
</attr>
2

В случае необходимости описать преобразование, можно указать только один из этих атрибутов.

Пример.

Создать таблицу со всеми возможными сочетаниями игроков в бильярд из двух команд:

Игроки первой команды:

Вася
Маша
Никита

Игроки второй команды:

Алёна
Петя
Лиза

Решение: Нужно только подключить источники данных к портам компонента CROSS_JOIN. Настройка атрибутов компонента не требуется.

В результате получится такой набор пар игроков в бильярд:

Вася | Алёна
Вася | Петя
Вася | Лиза
Маша | Алёна
Маша | Петя
Маша | Лиза
Никита | Алёна
Никита | Петя
Никита | Лиза

Заметка: Ребро, по которому передаётся наибольшее количество записей, должно быть подключено к первому входному порту.