Во-первых надо создать табличку в которой будут храниться выполненные запросы и количество результатов в выборке.
[spoiler]
Откроем /bitrix/admin/sql.php?lang=ru&del_query=Y и выполним запрос:
drop table if exists my_search_autocomplete;
create table my_search_autocomplete
(
ID int(11) not null auto_increment,
FILTER_MD5 varchar(32),
SEARCH_PHRASE varchar(100),
RESULT_COUNT int(11),
CONSTRAINT pk_search_autocomplete PRIMARY KEY (ID),
index ix_autocomplete (FILTER_MD5, SEARCH_PHRASE)
)
|
Теперь встает задача сбора этой статистики.
Копируем шаблон search.page в шаблон сайта и в скопированном шаблоне делаем result_modifier.php следующего содержания:
<?
$query_len = strlen($arResult["REQUEST"]["~QUERY"]);
if($query_len > 0 && $query_len < 100)
{
//Add here any data than will influence results count
$filter_md5 = md5(SITE_ID."|".$arResult["REQUEST"]["~TAGS"]."|".$arResult["REQUEST"]["WHERE"]."|".$arParams["CHECK_DATES"]);
$rsQueryStat = $DB->Query("
SELECT *
FROM my_search_autocomplete
WHERE FILTER_MD5 = '".$filter_md5."'
AND SEARCH_PHRASE = '".$DB->ForSQL($arResult["REQUEST"]["~QUERY"])."'
");
//if($arResult["NAV_RESULT"]->NavRecordCount >= COption::GetOptionInt("search", "max_result_size"))
// $result_count = -1; //Infinity needs proper display in search.input component
//else
$result_count = $arResult["NAV_RESULT"]->NavRecordCount;
$arQueryStat = $rsQueryStat->Fetch();
if(!$arQueryStat)
{
$DB->Add("my_search_autocomplete", array(
"FILTER_MD5" => $filter_md5,
"SEARCH_PHRASE" => $arResult["REQUEST"]["~QUERY"],
"RESULT_COUNT" => $result_count,
));
}
elseif($arQueryStat["RESULT_COUNT"] != $result_count)
{
$DB->Query("
UPDATE my_search_autocomplete
SET RESULT_COUNT = ".$result_count."
WHERE FILTER_MD5 = '".$filter_md5."'
AND SEARCH_PHRASE = '".$DB->ForSQL($arResult["REQUEST"]["~QUERY"])."'
");
}
while($arQueryStat = $rsQueryStat->Fetch())
$DB->Query("DELETE from my_search_autocomplete WHERE ID = ".$arQueryStat["ID"]);
$arResult["FILTER_MD5"] = $filter_md5;
}
?> |
Статистика набирается. Вопрос как вывести?
Ответ - копируем компонент bitrix:search.tags.input в my:search.input и в шаблоне search.page вместо
<input type="text" name="q" value="<?=$arResult["REQUEST"]["QUERY"]?>" size="40" /> |
подключаем этот "новый" компонент :
<?
$APPLICATION->IncludeComponent(
"my:search.input",
"",
array(
"NAME"=>"q",
"VALUE"=>$arResult["REQUEST"]["~QUERY"],
"FILTER_MD5"=>$arResult["FILTER_MD5"],
),
$component);
?> |
Осталось search.input "доточить".
Итак
1. В шаблоне в файле script.js заменяем
/bitrix/components/bitrix/search.tags.input/search.php |
на
/bitrix/components/my/search.input/search.php |
2 в result_modifier.php
перед
$arParams["~ADDITIONAL_VALUES"] = $arParams["ADDITIONAL_VALUES"]; |
добавляем
$arParams["ADDITIONAL_VALUES"] .= ",md5:".$arParams["FILTER_MD5"]; |
3 В файле search.php заменяем код выборки на:
if(!empty($_REQUEST["search"]))
{
if(strToLower($arParams["sort"]) == "name")
$strOrder = "ORDER BY NAME ASC, CNT DESC";
else
$strOrder = "ORDER BY CNT DESC, NAME ASC";
$db_res = $DB->Query("
SELECT SEARCH_PHRASE NAME, RESULT_COUNT CNT
FROM my_search_autocomplete
WHERE FILTER_MD5 = '".$DB->ForSQL($arParams["md5"], 32)."'
AND SEARCH_PHRASE LIKE '".$DB->ForSQL($_REQUEST["search"], 100)."%'
".$strOrder."
LIMIT 0, ".intVal($arParams["pe"])."
");
if($db_res)
{
while($res = $db_res->Fetch())
$arResult[] =$res;
}
?><?=CUtil::PhpToJSObject($arResult)?><?
require_once($_SERVER["DOCUMENT_ROOT"].BX_ROOT."/modules/main/include/epilog_after.php");
die();
}
|
PS Ну а дальше безгранично развиваем функционал, удаляем лишнее и исправляем ошибки!
PPS Например можно добавить время актуальности и "чистить" "нулевые" или "бесконечные" результаты и т.п.
PPS Как кастомизировать search.form надеюсь не надо рассказывать