В мире веб-разработки эффективное управление данными имеет решающее значение. Bitrix framework предлагает систему ORM (объектно-реляционное сопоставление), которая упрощает взаимодействие с базами данных. С Bitrix ORM разработчики могут беспрепятственно работать с базами данных и без особых усилий выполнять задачи по агрегации данных.
Агрегация данных включает сбор и обобщение информации из нескольких записей базы данных. Bitrix ORM предоставляет удобные методы для эффективного выполнения задач по агрегации данных. Разработчики могут использовать различные функции ORM: функции фильтрации, группировки и агрегирования, для эффективного извлечения и обработки данных.
Работая в системе Битрикс24, возникает необходимость сложной агрегации данных через ORM, потому что старые методы ядра становятся устаревшими и удаляются при обновлении.
Показательным примером будут «Задачи» Битрикс24. Если в старом классе CTasks мы получали полную информацию о задаче из метода GetList, то в новых версиях битрикс24 метод объявлен устаревшим, теперь необходимо объединять таблицы отношениями one-to-one и one-to-many.
Как пример возьмем ситуацию, когда надо получить информацию о Задачах Битрикс24. Информация по задачам разбита по таблицам UserTable, WorkgroupTable, ElapsedTimeTable. Мы объединим их через Data Manager методом GetList c использованием секции runtime:
use Bitrix\Tasks\Integration\Report\Internals\TaskTable;
use Bitrix\Main\UserTable;
use Bitrix\Socialnetwork\WorkgroupTable;
use Bitrix\Tasks\Internals\Task\ElapsedTimeTable;
TaskTable::getList([
'select' => [
'ID',
'TITLE',
'RESPONSIBLE_ID',
'CREATED_BY',
'CREATED_BY_USER_' => 'CREATED_BY_TABLE.*',
'RESPONSIBLE_ID_' => 'RESPONSIBLE_TABLE.*',
'WORKGROUP_TABLE_' => 'WORKGROUP_TABLE.*',
],
'runtime' => [
new ReferenceField(
'WORKGROUP_TABLE',
WorkgroupTable::class,
['=this.GROUP_ID => 'ref.ID']
),
new ReferenceField(
'CREATED_BY_TABLE',
UserTable::class,
['=this.CREATED_BY' => 'ref.ID']
),
new ReferenceField(
'RESPONSIBLE_TABLE',
UserTable::class,
['=this.RESPONSIBLE_ID' => 'ref.ID']
),
],
]);
ReferenceField соединяет таблицы по ключам в таблице TaskTable по полю GROUP_ID соединяем таблицу WorkgroupTable, то же самое с таблицей UserTable. Объединив таблицы, мы можем применять по полям параметры фильтрации Bitrix ORM.
Отмечаем, что ReferenceField создает связь и one-to-one и one-to-many, поэтому если вы хотите иметь только уникальные значения, группируем данные через функции агрегации. Как пример берём таблицу ElapsedTimeTable и считаем все время, потраченное на задачу:
ElapsedTimeTable::getList([
'select' => [
'TASK_ID',
new ExpressionField('TASK_TIME', 'SUM(SECONDS)', ['SECONDS']),
],
'group' => ['TASK_ID'],
]);
Усложним пример, добавив класс ExpressionField для создания динамических полей, где будем считать время затраченное на задачу из таблицы ElapsedTimeTable
TaskTable::getList([ 'select' => [ 'ID', 'TITLE', 'RESPONSIBLE_ID', 'CREATED_BY', 'CREATED_BY_USER_' => 'CREATED_BY_TABLE.*', 'RESPONSIBLE_ID_' => 'RESPONSIBLE_TABLE.*', 'WORKGROUP_TABLE_' => 'WORKGROUP_TABLE.*', new \Bitrix\Main\Entity\ExpressionField( 'TASK_TIME', '%s', ['ID'], [ 'data_type' => '\Bitrix\Main\ORM\Fields\StringField', 'title' => 'TASK_TIME', 'fetch_data_modification' => function () { return [ function ($value, $query, $data, $alias) { if ($value) $value = ElapsedTimeTable::getList([ 'select' => [ new ExpressionField('TASK_TIME', 'SUM(SECONDS)', ['SECONDS']) ], ‘filter’ => [ 'TASK_ID' => $value ], ‘limit’ => 1 ])->fetch(); return $value['TASK_TIME']; } ]; } ] ), ], 'runtime' => [ new ReferenceField( 'WORKGROUP_TABLE', WorkgroupTable::class, ['=this.ID' => 'ref.ID'] ), new ReferenceField( 'CREATED_BY_TABLE', UserTable::class, ['=this.CREATED_BY' => 'ref.ID'] ), new ReferenceField( 'RESPONSIBLE_TABLE', UserTable::class, ['=this.RESPONSIBLE_ID' => 'ref.ID'] ), ],
]);
Стоит отметить, что ExpressionField может не только работать с функциями агрегации COUNT, SUM, MAX, MIN, AVG, но и имеет возможность динамически создавать ячейку в строке таблицы на основании данных строки. Как видно на примере, мы в ExpressionField четвертым параметром создаем динамические данные, которые получают айди задачи и подсчитывают затраченное время на задачу из таблицы ElapsedTimeTable. Также стоит отметить, что если вы создаете динамическое поле через ExpressionField, то к нему нельзя применять фильтрацию ORM.
Bitrix ORM упрощает взаимодействие с базой данных и позволяет разработчикам более эффективно работать с данными. Он предлагает интуитивный подход к управлению базами данных с использованием объектно-ориентированных концепций. Благодаря встроенным функциям агрегирования данных, Bitrix ORM позволяет разработчикам без труда выполнять сложные вычисления и обобщения. Используя возможности ORM в Битриксе, разработчики могут с легкостью создавать надежные и масштабируемые веб-приложения.