Агрегирующие поля в объектах

Рейтинг: 3.0000  
Новая
Предложил Малюгин Виктор 22.01.2019 18:45:26

Агрегирующие поля в объектах

Раньше чтоб получить, например, список групп пользователя я мог выполнить запрос
$arUser = \Bitrix\Main\UserTable::getList([
  'select' => ['ID', 'LOGIN', 'GROUP_LIST'],
  'runtime' => [
      new \Bitrix\Main\Entity\ReferenceField(
          'GROUP_REF',
          \Bitrix\Main\UserGroupTable::getEntity(),
          [
              '=this.ID' => 'ref.USER_ID'
          ]
      ),
      new \Bitrix\Main\Entity\ExpressionField(
          'GROUP_LIST',
          'GROUP_CONCAT(DISTINCT %s SEPARATOR "[#]")',
          'GROUP_REF.GROUP_ID',
          [
              'fetch_data_modification' => function () {
                  return [
                      function ($val) {
                          if (empty($val)) {
                              return [];
                          }

                          return explode("[#]", $val);
                      }
                  ];
              }
          ]
      )
  ]
])->fetch();

и в $arUser['GROUP_LIST'] был список идентификаторов групп.
В парадигме объектов агрегирующие поля запрещены - при fetchObject бросается исключение "Result of query with aggregation could not be fetched as an object". Хотя если в файле bitrix/modules/main/lib/orm/query/result.php в методе initializeFetchObject закомментировать проверку на наличие в запросе агрегирующих полей [if (!empty($this->query->getGroupChains()))] и ExpressionField'у задать тип ArrayField, то в результате fetchObject прекрасно возвращается поле содержащее массив значений.
Идея: разрешить использование агрегирующих полей, либо доработать АПИ так, чтоб можно было получать нечто подобное без лишних запросов.

Рейтинг: 0  
Малюгин Виктор 03.07.2019 08:55:07
все еще в статусе "новая"??
Рейтинг: 0  
Малюгин Виктор 03.07.2019 08:55:35
полгода прошло!
Рейтинг: 0  
Малюгин Виктор 03.07.2019 08:58:14
что нужно, чтоб в "голосование" перешла идея?
Рейтинг: 1  
Медведев Дмитрий 09.07.2019 19:14:25
В общем случае fetch в виде объекта не допускается, т.к. результат может не иметь смысла в объектном выражении. Например, если выбирать
SEL ECT LAST_NAME, COUNT(*) FR OM b_user GROUP BY LAST_NAME
то результат никак нельзя назвать инстансом юзера, это будет просто произвольная информация.

А в вашем частном примере действительно никаких проблем нет, можно было бы разрешить фетч объекта.

Давайте попробуем сформулировать правило, когда в группировке объекты допустимы и имеют смысл? В "физике" орм минимальное условие существования объекта - это наличие primary ключ. Тогда можно сказать, что если в запросе primary не агрегируется (то есть остается в неизменном виде), то можно допустить фетч объекта.