У CMS Bitrix есть замечательный компонент поиска (в том числе ajax поиск) — «bitrix:search.title», который может в строке поиска отдавать пользователю результат предварительных данных. По умолчанию в админке для переиндексации(создания индекса) поиска есть небольшой набор модулей — Блоги, Форумы, Инфоблоки, Статическийе Файлы.Список модулей доступных для переиндексации можно расширить своим модулем, в котором можно организовать произвольную таблицу с данными и при этом данные из которой должны участвовать в общем поиске.
Вот простая строка которая «припишет» ваш модуль в список доступных для индексации:
1 2 3 |
RegisterModuleDependences("search", "OnReindex", "coderun.framework", '\Coderun\Framework\SearcheProductXMLID', "OnSearchReindex"); |
coderun.framework — название вашего модуля, реально существующего в системе Bitrix
\Coderun\Framework\SearcheProductXMLID — Полный путь до вызываемого класса модуля с namespace в нашем случае
OnSearchReindex — Имя метода с всей логикой из класса SearcheProductXMLID
Сам же метод RegisterModuleDependences нужно вызывать один раз, либо при установке модуля, либо просто один раз где нибудь. При вызове этого метода в таблицу b_module_to_module попадает соответствующая запись.
Если вам не нужно данное событие, то вызовите обратный метод UnRegisterModuleDependences с тем же набором параметров что и RegisterModuleDependences
Далее вам нужно описать действия в методе OnSearchReindex вашего класса SearcheProductXMLID:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
//...class \Coderun\Framework\SearcheProductXMLID /** * * @param array $NS - SITE_ID,MODULE_ID,SESS_ID,CNT,CLEAR * @param array $oCallback - MODULE, max_execution_time,CNT,SESS_ID * @param string $callback_method - Index * @return boolean|array */ public function OnSearchReindex(&$NS, $oCallback, $callback_method) { if (!check_bitrix_sessid($NS['SESS_ID'])) { return false; } $arCallback = (array) $oCallback; $max_time = $arCallback['max_execution_time']; $arResult = array(); $page = $NS['CNT'] + 1; \CModule::IncludeModule('iblock'); //Пример запроса к инфоблоку $dbQuery = \CIBlockElement::GetList( ['ID' => 'ASC'], ['IBLOCK_ID' => 4, 'ACTIVE' => 'Y'], false, ['nPageSize' => 1000, 'iNumPage' => $page, 'checkOutOfRange' => true], ['ID', 'IBLOCK_ID', 'PROPERTY_ARTICUL_MAIN', 'DETAIL_PAGE_URL', 'NAME'] ); $end_id = 0; \CModule::IncludeModule('search'); while ($arTmp = $dbQuery->GetNext()) { $arResult = array( "ID" => $arTmp["ID"], "LID" => $NS['SITE_ID'],//ИД сайта "DATE_CHANGE" => date('d.m.Y H:i:s'), "URL" => $arTmp['DETAIL_PAGE_URL'],//Полный путь до искомой единицы "PERMISSIONS" => array(2), "TITLE" => $arTmp['NAME'] . ' ' . $arTmp['PROPERTY_ARTICUL_MAIN_VALUE'], "BODY" => $arTmp['NAME'], 'PARAM1' => 'maincatalog',//доп условие для компонента 'PARAM2' => 4,//ИД инфоблока для доп условия в компоненте ); $end_id = \CSearch::Index($NS['MODULE_ID'], $arTmp["ID"], $arResult); if (!self::timeLimitEx($max_time)) {//ограничения по времени break; } } $NS['CNT'] = $page; $NS['ID'] = $end_id; if (intval($end_id) === 0) { return false; } return $end_id; } |
В примере делается запрос к инфоблоку товаров и вытаскивается некоторое свойство товара, которое затем помещается и TITLE индекса, по которому и будет происходить быстрый поиск в компоненте bitrix:search.title.
В качестве данных можно взять любые данные из ваших таблиц, значения из которых должны попасть в поиск и работать при запросах через стандартный компонент Bitrix.
Суть метода такова что пока возвращается не FALSE — будет происходить следующий шаг индексации.
Параметр $NS передаётся по ссылке и возможно вам из него пригодятся некоторые ключи.
Во время переиндексации Bitrix работает с таблицами:
b_module_to_module — сюда собственно и попадает переданный массив данных для \CSearch::Index
b_search_content_title — поставщик данных для быстрого поиска, она же связанна с таблицей выше через SEARCH_CONTENT_ID
Так же, в компоненте bitrix:search.title есть особенность, что для поиска он берёт данные только от модуля iblock, если в вашей версии компонента нет «адекватных» способов изменить эту логику — тогда кастомизируйте компонент и добавляйте в условие функции $obTitle->Search следующий код:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
//..../bitrix/components/coderun/search.title/component.php //Эта часть кода скорее всего у вас есть $exFILTER = array( 0 => CSearchParameters::ConvertParamsToFilter($arParams, "CATEGORY_" . $i), ); $exFILTER[0]["LOGIC"] = "OR";//Фильтр логики если несколько модулей if ($arParams["CHECK_DATES"] === "Y") { $exFILTER["CHECK_DATES"] = "Y"; } //Добавляем поиск по вашему модулю $exFILTER[0][0]['=MODULE_ID']='coderun.framework';//Добавляем это //+ это что бы работал поиск по iblock как и раньше $exFILTER[0][1]['=MODULE_ID']='iblock'; $exFILTER[0][1]['PARAM1']='maincatalog'; $exFILTER[0][1]['PARAM2']=[4]; $arOthersFilter[] = $exFILTER; $j = 0; $obTitle = new CSearchTitle; $obTitle->setMinWordLength($_REQUEST["l"]); if ($obTitle->Search( $arResult["alt_query"] ? $arResult["alt_query"] : $arResult["query"] , $arParams["TOP_COUNT"] , $exFILTER , false , $arParams["ORDER"] ))............ |