A
A
Alexander2018-11-16 11:51:00
1C-Bitrix
Alexander, 2018-11-16 11:51:00

How to reduce bitrix sampling time via GetList?

On the site 1 user does not own 1 category in the infoblock, it contains the user's subscriptions. It is necessary to make a selection of users who do not have subscriptions with certain IDs in the list.
I do the following:
- I get a list of all categories (there are about 20k) using GetList
- I go through each category and pull out all category subscriptions (about 5 pieces) through GetList each subscription through if I check if the required subscription belongs to the desired id, discard her. If everything is OK, we get the user's email.
I will give the code below.
The problem is that the script runs for more than 40 seconds, which, it seems to me, is a lot. What to do?

Function code
public static function collectSendList(){
       // Если ID подписки(TYPE) равен одному из этих ид, отбрасываем ее
      $donateList = array(2698, 2699, 2700, 2705, 37155, 41371);

      // Выборка всех всех групп пользователей
      $users_group = \CIBlockSection::GetList(
                        array(), 
                        array(
                            "IBLOCK_ID" => 7,
                            "LEVEL" => "1",
                            "ACTIVE" => "Y"
                            ),
                        false,
                        array("ID")
                    );
       // Перебираем все группы
        while ($group = $users_group->Fetch()) {
            // Выборка подписок определенной группы
            $subs = \CIBlockElement::GetList(
                        array(), 
                        array(
                            "IBLOCK_ID" => 7,
                            "SECTION_ID" => $group['ID'],
                            "ACTIVE" => "Y"
                            ),
                        false,
                        false,
                        array("PROPERTY_TYPE", "PROPERTY_USER")
                    );

            $donator = null;

           // перебор подписок
            while ($sub = $subs->Fetch()){
                $donator = $sub;
                if(!array_search($sub['PROPERTY_TYPE_VALUE'], $donateList)){
                    $donator = null;
                    break;
                }
            }
            if($donator !== null){
                // Получаем емайл пользователя
                $result = \Bitrix\Main\UserTable::getList(array(
                    'select' => array('ID','EMAIL'),
                    'filter' => array('ID' => $donator['PROPERTY_USER_VALUE'])
                ))->Fetch();
                print_r($result);
            }
        }
    }

Answer the question

In order to leave comments, you need to log in

2 answer(s)
R
Roman Gritsuk, 2018-11-16
@winer

Can be done in 2 requests.
1) we get IDs of categories in which there are subscriptions we don’t need
2) We make a request for categories, excluding those received in 1

\Bitrix\Main\Loader::includeModule("iblock");
$donateList = array(2698, 2699, 2700, 2705, 37155, 41371);

$IBLOCK_ID = 7;
$arSelect = Array("IBLOCK_SECTION_ID");
$arFilter = Array(
    "IBLOCK_ID" => $IBLOCK_ID,
    "ACTIVE" => "Y",
    "PROPERTY_TYPE" => $donateList
);

$res = CIBlockElement::GetList(array("IBLOCK_SECTION_ID" => "ASC"), $arFilter, ["IBLOCK_SECTION_ID"], false, $arSelect);
$blackListSections = [];
while ($arItem = $res->Fetch()) {
    $blackListSections[] = $arItem["IBLOCK_SECTION_ID"];
}

$users_group = \CIBlockSection::GetList(
    array(),
    array(
        "IBLOCK_ID" => $IBLOCK_ID,
        "!ID" => $blackListSections
    ),
    false,
    array("ID")
);
//и т.д.

A
Antony Tkachenko, 2018-11-16
@LemonFox

Remove database queries from loops

$sections = [];
while ($group = $users_group->Fetch()) {
  $sections[] = $group['ID'];
}
...
$subs = \CIBlockElement::GetList(
    array(),
    array(
        "IBLOCK_ID" => 7,
        "SECTION_ID" => $group['ID'],
        "ACTIVE" => "Y",
        "!PROPERTY_TYPE" => $donateList //тут не уверен, нужно потестить, есть ли у bitrix NOT IN
    ),
    false,
    false,
    array("PROPERTY_TYPE", "PROPERTY_USER")
);
...

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question