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 на пыхе.


Пишем Sphinx-index:

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: http://adw0rd.ru/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. Для чего нужны дельта-индексы и как их готовить?


Комментарии (5) на запись «Легкая замена стандартного поиска в SMF на Sphinx»

» Трекбеки скрыты, показать их?
  1. phpdude | 30.07.2009 в 22:47

    это да, решение и правда пиздец легкое, ибо смф тот еще говнокод ...

  2. adw0rd | 30.07.2009 в 23:01

    угу, может новые версии движков лучше?

  3. epsyl | 03.08.2009 в 14:00

    лучше-то лучше

    но мы апгрейд делать не будем :)

  4. adw0rd | 03.08.2009 в 14:03

    epsyl, ну это понятно :)

  5. Gena | 28.08.2009 в 09:26

    вот это решение, а я сидел тупил целыми днями, совсем случайно набрел на блог

Оставить комментарий