Приветствую, коллеги Для внешних приложений, а также для массовой обработки часто требуется выгрузить все имеющиеся сущности на портале (лиды / сделки и т.п.). Однако по умолчанию рест-запросы позволяют получить только 50 сущностей за раз: https://dev.1c-bitrix.ru/rest_help/rest_sum/start.php В итоге, если в базе сотня тысяч лидов, приходится направлять большое число запросов, из-за чего можно столкнуться с ограничениями. Но есть специальный метод, batch, позволяющий объединить запросы пачками по 50 штук: https://dev.1c-bitrix.ru/rest_help/general/batch.php Таким образом, за 1 запрос можно получить уже 2500 сущностей. Но я попробовал объединить batch в batch, и это сработало. Таким образом, можно создать сложный вложенный запрос, которым возможно получить, к примеру, все лиды на портале. Предела вложенностей батчей друг в друга я не нашел, если сущностей более 125 000, просто увеличиваем уровень вложенности.
Такого способа я не видел ни в одном руководстве / форуме, поэтому и возник вопрос - какие могут быть подводные камни у этого способа? Может быть, есть причины, по которым это не используют?
Однако, для формирования батчей нужно изначально знать общее количество сущностей данного типа, для чего нужен один предварительный запрос, на основании которого уже формируется основной запрос. В пределах одного батча можно обращаться к результатам предыдущих запросов, что позволяет использовать параметр start (подсчитывает общее количество и значительно тормозит обработку) только в первом запросе каждого батча, а далее передавать "ID > крайнего ID из прошлого запроса" и start = -1 (отключает подсчет), что ускоряет время обработки. Обратиться к результатам последнего запроса другого батча из пачки я не смог. Что-то вроде $result['batch1']['lead_list50'][49][ID] или $result['batch1']['result']['lead_list50'][49][ID] не работает. Может быть, есть способ это сделать?
Для эксперимента взял портал с примерно 135 000 лидов, их выгрузка с несколькими базовыми полями заняла около 10-15 секунд. Пример кода
Ну во-первых это работает У меня правда значительно меньшие объемы...
и действительно очень шустро -- двумя запросами на один список...
Только убедительная просьба -- дабы вы сами себя не ругали потом -- пишите функциональней/универсальнее == три параметра и все становится универсальнее... как пример Вы ведь не только лиды вытягиваете?
Load_List($URL_BATCH,$appMetod,$arrField)
Понимаете какие строки вынести в параметры?
Код
//----------запрос общего количества-----------
$queryUrl = '.../crm.lead.list'; //добавить адрес вебхука
...
$batch['cmd']['lead_list'.$i] = 'crm.lead.list?'
...
//---------основной запрос---------
$queryUrl = '.../batch'; //добавить адрес вебхука
...
'select' => array('ID', 'TITLE', 'NAME', 'STATUS_ID'), //здесь указываем все поля, которые нужно получить
...
Благодарю, подправил с параметрами По этому посту на хабре сначала и начинал делать, но потом немного дополнил получением последнего ID из прошлого запроса батча и объединением всех батчей в один запрос "Впрочем, таким образом достаточно просто перегрузить сервер, который даже при соблюдении скорости запросов начинает обрывать соединение и уходить в таймауты." - вот это больше всего испугало в параллельности, но как-нибудь попробовать можно будет
по этому методу действительно, не возникает проблем с "квотированием" даже на больших объемах, но проблема c тем за какое время отдаст сервер данные и куда их впихнуть за время ограничивающее работу скрипта.
У меня за типовые 30 секунд улетело очень быстро...
Дополнение надо еще обязательно парсить ответ на error
На выборку данных из Б24 работает. Переделал пример на update пользовательского поля и вот тут сервер помер, даже не сказал что привышино количество запросов, а 4 минуты делал вид что обновляет 700 записей и в результате выдал result0 {"error":"INTERNAL_SERVER_ERROR","error_description":"Internal server error"}