Блок "Похожие статьи" в 1С Битрикс news.list

Несмотря на размах Битрикса в его функционале нет готового решения для вывода похожих статей. Но ниже представлен простой способ генерации этого блока. Причём создавать его мы будем автоматически; собирать список вручную же легче всего через свойство привязки элементов, но это уже совсем просто.
Итак, какая идея?

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

Считаю, что зачастую этот функционал нужен на странице детального просмотра статьи. Как вы можете знать, в Битриксе news.detail отвечает за детальный просмотр элемента, а news.list за вывод списка элементов. Не вижу причин нарушать эту логику, поэтому сам блок мы вставим в конец шаблона детальной страницы, а блоком будет являться второй компонент. Как вы могли догадаться, самым сложным здесь является генерация массива для фильтрации.
Фильтр

Код отвечающий за массив для фильтрации статей.

<?
// похожие статьи
// удаляем лишние знаки
echo $tmpName = str_replace(array(".", ",", "?", "!", "-"), " ", trim($arResult["NAME"]." ".$arResult["TAGS"]));

// если есть с чем работать
if (strlen($tmpName) > 0){
    $arLooksLike = array(
        "INCLUDE_SUBSECTIONS" => "Y",
        "!ID"                 => intval($arResult["ID"]) // не данный элемент
    );

    $stuffWords = Array("в", "на", "по", "из"); // эти слова не несут смысла
    // массив, который будет использоваться для поиска в имени или тегах
    $NameItems = explode(" ", $tmpName);
    $itemsArray = array();
    foreach ($NameItems as $item){
        if (in_array($item, $stuffWords)){ // убираем предлоги
            continue;
        }
        if (strlen($item) > 1){ // редко бывают значимые слова в одну букву
            $itemsArray[] = array("NAME" => "%".$item."%");  // ищем элементы, у которых выбранное свойство есть в названии
            $itemsArray[] = array("TAGS" => "%".$item."%");  // ищем элементы, у которых выбранное свойство есть в поисковых тегах
        }
    }
    $addFArray = array(
        array(array_merge(array("LOGIC" => "OR"), $itemsArray)),
    );

    // массив для фильтра
    $GLOBALS["similarArticles"] = array_merge($arLooksLike, $addFArray);
}
?>

Не думаю, что здесь нужны какие-то пояснения: я привёл комментарии, а откуда $arResult вы и сами должны знать; отмечу лишь, что сам массив должен быть глобальным, такова логика системы.
Подключение компонента

Это может быть слишком очевидно, но приведу здесь код для вызова news.list для вывода статей. Вещи, на которые стоит обратить внимание, я прокомментировал. Подробнее про все поля можете прочитать здесь.

<? $APPLICATION->IncludeComponent(
    "bitrix:news.list",
    "similar-articles",
    Array(
        "AJAX_MODE"                       => "N",
        "IBLOCK_TYPE"                     => $arResult["IBLOCK_TYPE"], // Тот же тип инфоблока
        "IBLOCK_ID"                       => $arResult["IBLOCK_ID"], // Тот же инфоблок
        "NEWS_COUNT"                      => "5",
        "SORT_BY1"                        => "SORT",
        "SORT_ORDER1"                     => "ASC",
        "SORT_BY2"                        => "ACTIVE_FROM",
        "SORT_ORDER2"                     => "DESC",
        "FILTER_NAME"                     => "similarArticles", // Тот самый фильтр, что мы сгенерировали
        "FIELD_CODE"                      => "PREVIEW_TEXT",
        "PROPERTY_CODE"                   => "",
        "CHECK_DATES"                     => "Y",
        "DETAIL_URL"                      => "",
        "PREVIEW_TRUNCATE_LEN"            => "",
        "ACTIVE_DATE_FORMAT"              => "j F Y",
        "SET_TITLE"                       => "N", // Стараемся ни на что не влиять
        "SET_BROWSER_TITLE"               => "N", // Стараемся ни на что не влиять
        "SET_META_KEYWORDS"               => "N", // Стараемся ни на что не влиять
        "SET_META_DESCRIPTION"            => "N", // Стараемся ни на что не влиять
        "SET_LAST_MODIFIED"               => "N", // Стараемся ни на что не влиять
        "INCLUDE_IBLOCK_INTO_CHAIN"       => "N", // Стараемся ни на что не влиять
        "ADD_SECTIONS_CHAIN"              => "N", // Стараемся ни на что не влиять
        "HIDE_LINK_WHEN_NO_DETAIL"        => "N",
        "PARENT_SECTION"                  => "", // Все разделы
        "PARENT_SECTION_CODE"             => "", // Все разделы
        "INCLUDE_SUBSECTIONS"             => "Y", // Все разделы
        "CACHE_TYPE"                      => "A",
        "CACHE_TIME"                      => "36000000",
        "CACHE_FILTER"                    => "Y",
        "CACHE_GROUPS"                    => "N",
        "PAGER_TEMPLATE"                  => ".default",
        "DISPLAY_TOP_PAGER"               => "N",
        "DISPLAY_BOTTOM_PAGER"            => "N",
        "PAGER_TITLE"                     => "Новости",
        "PAGER_SHOW_ALWAYS"               => "N",
        "PAGER_DESC_NUMBERING"            => "N",
        "PAGER_DESC_NUMBERING_CACHE_TIME" => "36000",
        "PAGER_SHOW_ALL"                  => "N",
        "PAGER_BASE_LINK_ENABLE"          => "N",
        "SET_STATUS_404"                  => "N",
        "SHOW_404"                        => "N",
        "MESSAGE_404"                     => "",
        "AJAX_OPTION_JUMP"                => "N",
        "AJAX_OPTION_STYLE"               => "Y",
        "AJAX_OPTION_HISTORY"             => "N",
    ),
    $component // Потому что подключаем внутри шаблона
); ?>

Итог

Как видите, всё действительно просто. Но есть некоторые проблемы, например, не учтена релевантность в сортировке и предлоги забиваются вручную.

Если у вас есть идеи для доработки решения, вопросы по расширению функционала и просто свои мысли, пишите их в комментариях.

< Возврат к списку

Контакты
ИП Мироненко О.В.
ИНН: 463310474220
ОГРНИП: 317774600094220
Пн-Вс круглосуточно
Работаем удалённо!
Задать вопрос

Нажимая на кнопку «Отправить», Вы даете согласие на обработку своих персональных данных и получение информационных сообщений.