Легкая замена стандартного поиска в SMF на Sphinx
Потребовалась замена на ПыхоФоруме стандартного поиска на Sphinx, а также сделать нормальный поиск по пользователям. Для этого потребовалось установить Sphinx и движок для MySQL - SphinxSE.
Подготавливаем индекс
Пишем Sphinx-source:
source pyha_forum { type = mysql sql_host = localhost sql_user = pyha sql_pass = sql_db = pyha sql_port = 3306 sql_sock = /tmp/mysql.sock sql_query_pre = SET NAMES utf8 sql_query_pre = SET CHARACTER SET utf8 sql_query = \ select ID_MSG, concat('user:',posterName) as posterName, subject, body \ from smf_messages sql_query_info = select ID_MSG, posterName, subject, body from smf_messages where ID_MSG = $id sql_ranged_throttle = 0 }
Поиск по пользователям реализован за счет "concat('user:',posterName)". И достаточно в поисковую строку ввести "user:adw0rd php", чтобы найти все мои сообщения связанные с php на пыхе.
index pyha_forum { source = pyha_forum path = /var/sphinxsearch/pyha_forum docinfo = extern mlock = 0 morphology = stem_enru min_word_len = 2 charset_type = utf-8 charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F min_infix_len = 2 enable_star = 1 }
Далее, создаем таблицу для Sphinx'a:
CREATE TABLE `sphinx_smf_messages` ( `id` int(11) NOT NULL, `weight` int(11) NOT NULL, `query` varchar(3072) NOT NULL, `group_id` int(11) default NULL, KEY `query` (`query`(1024)) ) ENGINE=SPHINX DEFAULT CHARSET=utf8 CONNECTION='sphinx://localhost:3312/pyha_forum';
Подробнее о SphinxSE: /2009/mysql-sphinxse/
Меняем код в SMF
В /Source/Search.php (строка ~1377) ищем:
$request = db_query( "SELECT " . (empty($search_params['topic']) ? 'lsr.ID_TOPIC' : $search_params['topic'] . ' AS ID_TOPIC') . ", lsr.ID_MSG, lsr.relevance, lsr.num_matches FROM ({$db_prefix}log_search_results AS lsr" . ($search_params['sort'] == 'numReplies' ? ", {$db_prefix}topics AS t" : '') . ") WHERE ID_SEARCH = " . $_SESSION['search_cache']['ID_SEARCH'] . ($search_params['sort'] == 'numReplies' ? " AND t.ID_TOPIC = lsr.ID_TOPIC" : '') . " ORDER BY $search_params[sort] $search_params[sort_dir] LIMIT " . (int) $_REQUEST['start'] . ", $modSettings[search_results_per_page]", __FILE__, __LINE__);
и заменяем на
$request = db_query( "SELECT `sm`.`ID_TOPIC`, `ssm`.`id` AS `ID_MSG`, 1000 AS `relevance`, 0 AS `num_matches` FROM `sphinx_smf_messages` AS `ssm` LEFT JOIN `smf_messages` AS `sm` ON `ssm`.`id` = `sm`.`ID_MSG` WHERE `ssm`.`query` = '".$context['search_params']['search'].";weights=1,2,3' LIMIT " . (int) $_REQUEST['start'] . ", $modSettings[search_results_per_page]", __FILE__, __LINE__);
Вот и все, без лишних усложнений мы решили задачу! Если кто знаком с сорцами SMF - то понимает на сколько данное решение оказалось легким ;)
UP[2010-Feb-11]: Обновленная версия поиска:
$searchQuery = preg_replace('/[^[a-z][а-я]\s\d_-]+/iu', ' ', $context['search_params']['search']); $searchQuery = $searchQuery ? $searchQuery : '*'; $request = db_query( "SELECT `sm`.`ID_TOPIC`, `ssm`.`id` AS `ID_MSG`, 1000 AS `relevance`, 0 AS `num_matches` FROM `sphinx_smf_messages` AS `ssm` LEFT JOIN `smf_messages` AS `sm` ON `ssm`.`id` = `sm`.`ID_MSG` WHERE `ssm`.`query` = '".$searchQuery.";index=pyha_forum,pyha_forum_delta;weights=30,20,10,5;offset=".intVal($_REQUEST['start']). ";limit={$modSettings['search_results_per_page']};maxmatches=1000;mode=extended;groupby=day:created;sort=extended:@weight desc, created desc'", __FILE__, __LINE__ );
Если вы в недоумении что за "pyha_forum_delta", то читайте Sphinx. Для чего нужны дельта-индексы и как их готовить?
Комментарии
это да, решение и правда пиздец легкое, ибо смф тот еще говнокод ...
угу, может новые версии движков лучше?
лучше-то лучше
но мы апгрейд делать не будем :)
epsyl, ну это понятно :)
вот это решение, а я сидел тупил целыми днями, совсем случайно набрел на блог
Круто, хоть я в этом и не шарю, но буду вникать...
Оставьте свой комментарий