Как в Bitrix создать фасетные индексы инфоблоков программно через код php 3

В каждом интернет магазине на платформе Bitrix в каталоге есть и используется компонент «Умный фильтр» (bitrix:catalog.smart.filter), этот компонент входит в стандартный пакет поставки CMS Bitrix и позволяет организовать фильтрацию по свойствам товара в каталоге, что существенно для покупателя упрощает поиск нужного товара. Что бы фильтрация товаров по свойствам работала приемлемо быстро разработчики Bitrix придумали делать подборки результатов фильтра не из таблиц инфоблока, а при помощи специального «фасета».

С сайта Битрикс:

В функционал «Умного фильтра» встроен фасетный индекс. Использование «фасеты» на порядок ускоряет поиск внутри магазина. Фасетный поиск работает практически мгновенно, выполняет запросы по многим параметрам и не нагружает при этом систему.

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

При добавлении новых свойств товаров, Битрикс будет просить перестроить фасетный индекс и это сделать достаточно просто, через административную панель сайта:

Фасетный индекс битрикс
Пересоздание фасетного индекса битрикс из админки

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

Если речь идёт о регулярной загрузке товаров из учётной программе или при обмене товарами при помощи json, csv, xml и при автоматическом заведении свойств товара в информационном блоке встаёт вопрос о том как же программно пересоздать фасетный индекс, а так же как проверить нуждается ли информационный блок в пересоздании фасетного индекса.

Для того что бы проверить нуждается ли инфоблок в создании нового индекса достаточно функции:

В качестве параметра функция принимает ИД инфоблока и возвращает true — если требуется создание фасета.

И так, если мы знаем, что нужно создать фасет и хотим это сделать программно из кода, тогда воспользуемся следующей функцией:

При передаче функции стартовых параметров, начнётся процесс создания фасета. Если товаров много, то этот процесс лучше разбить на шаги. Что бы ограничить время на 1-н шаг, достаточно в массив параметров функции передавать ключ «max_execution_time» с нужным временем в секундах. При создании индекса, функция будет возвращать массив:

когда cnt станет равно total — значит можно прекратить процесс пересоздания индекса.

Ниже пример реализации пересоздания индекса на обычной странице сайта с передачей параметров между запросами через GET. Обработка каталога товаров с количеством более 100К позиций.

 

3 Comments

  1. Этот скрипт требует доработки. Вот что у меня получилось в итоге
    (не забудьте сменить iblock_id на свой)

    require_once($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_before.php");
    use \Bitrix\Main\Loader;
    Loader::includeModule('iblock');

    /**
    * Создание фасетного индекса
    * @param array $params Параметры запуска согласно ключам в функции
    */
    function reindex_iblock($params) {

    /**
    * Параметры по умолчанию
    */
    $default_params = [
    'cnt' => 0, //Всего элементов проиндексированно
    'last_id' => 0, //Последний элемент
    'total' => 0, //Всего элементов
    'iblock_id' => 12, //ИД инфоблока
    'max_execution_time' => 30, //время исполнения
    'first_start' => false, //Первый запуск
    ];

    $params = array_merge($default_params, $params);

    $index = \Bitrix\Iblock\PropertyIndex\Manager::createIndexer($params['iblock_id']);

    if ($params['first_start']) {
    $params['cnt'] = 0;
    $params['last_id'] = 0;
    $index->startIndex();
    $params['total'] = $index->estimateElementCount();
    $params['first_start'] = false;
    }

    $index->setLastElementId($params['last_id']);

    $res = $index->continueIndex($params['max_execution_time']);

    if ($res > 0) {
    $params['cnt'] += $res;
    $params['last_id'] = $index->getLastElementId();
    } else {

    $index->endIndex();

    \CBitrixComponent::clearComponentCache("bitrix:catalog.smart.filter");

    \CIBlock::clearIblockTagCache($params['iblock_id']);
    }

    return $params;
    }

    $default_params = [
    'cnt' => 0, //Всего элементов проиндексированно
    'last_id' => 0, //Последний элемент
    'total' => 0, //Всего элементов
    'iblock_id' => 12, //ИД инфоблока
    'max_execution_time' => 30, //время исполнения
    'first_start' => true, //Первый запуск
    ];

    $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[SCRIPT_NAME]";

    if (empty($_GET['reindex'])) {
    $load = reindex_iblock($default_params);

    $load['reindex'] = 'y';
    $load['step'] = 1;

    header("Refresh: 2;" . $url . '?' . http_build_query($load));
    exit();
    } elseif ($_GET['cnt'] == $_GET['total']) {
    die('Reindex finish!');
    } else {

    $load = reindex_iblock(
    [
    'cnt' => $_GET['cnt'] ? $_GET['cnt'] : 0,
    'last_id' => $_GET['last_id'] ? $_GET['last_id'] : 0,
    'total' => $_GET['total'] ? $_GET['total'] : 0,
    'iblock_id' => 12,
    'max_execution_time' => 20,
    'first_start' => false,
    ]
    );

    $load['reindex'] = 'y';

    $load['step'] += $_GET['step'];

    header("Refresh: 2;" . $url . '?' . http_build_query($load));

    exit();
    }

    1. Дурацкий парсер заменил кавычки.
      Елочки заменить на двойные кавычки.
      А апострофы на одинарные

  2. Замените кавычки на правильные. Дурацкий парсер этого сайта все переиначил

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *