База знаний

07.06.2017

Проблема

Поиск по сайту через Sphinx

Решение

1) Настраиваем Sphinx самым простым способом, вот мой конфиг:

source anyname_src
{
    
type            = mysql
    sql_host        
= localhost
    sql_user        
= <пользователь БД>
    
sql_pass        = <пароль к БД>
    
sql_db     = <БД>
    
sql_port        = 3306
    sql_query_pre
= SET NAMES utf8
    sql_query    
= SELECT id, name1, article, anons1 FROM <ваша таблица ..._shop> WHERE act1 = '1'
}

index anyname
{
    
source         = anyname_src
    path            
= /var/data/sphinx/anyname
    morphology    
= stem_ru
    min_word_len    
= 3
    html_strip    
= 1
    min_infix_len
= 3
    expand_keywords
= 1
}

indexer
{
    
mem_limit     = 128M
}

searchd
{
    
listen         = 127.0.0.1:9306:mysql41 #чтобы только локально можно было достучаться и только через соединение MySQL, т.е. просто через консоль работать не будет
    
log             = /var/log/sphinx/searchd.log
    query_log    
= /var/log/sphinx/query.log
    read_timeout    
= 5
    max_children    
= 30
    pid_file        
= /var/run/sphinx/searchd.pid
    seamless_rotate
= 1
    preopen_indexes
= 1
    unlink_old    
= 1
    workers        
= threads # for RT to work
    
binlog_path     = /var/lib/sphinx/
}

2) В шаблонах страниц вставляем тег , если его еще нет. После чего правим themes\functions\show_search.php, чтобы форма для поиска смотрела на страницу /search-results

3) Создаем через админку страницу "Результаты поиска" с URL /search-results и в ее содержимое вставляем только шаблонный тег

4) Дальше создаем шаблонный тег modules\shop\views\shop.view.show_sphinx_search_result.php, куда копируем содержимое файла modules\shop\views\shop.view.list.php и убираем лишнее (я убрал все, кроме вывода списка товара, добавил вывод сообщений если ничего не найдено или не указана фраза для поиска)

5) Добавляем в modules\shop\shop.model.php функцию для шаблонного тега:

/**
* Генерирует результат поиска товаров через Sphinx
*
* @param sting $searchword поисковая фраза
* @return array
*/
public function show_sphinx_result($searchword)
{
    
$pdo = new PDO('mysql:host=127.0.0.1;port=9306');
    
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

    
$stmt = $pdo->query("SELECT * FROM <название индекса из настроек Sphinx> WHERE MATCH('$searchword')");
    
$search_results = $stmt->fetchAll(PDO::FETCH_ASSOC);

    
$productsId = array();
    foreach (
$search_results as $value) {
        
$productsId[] = $value['id'];
    }

    
$this->result["rows"] = DB::query_fetch_all("SELECT DISTINCT id, [name], timeedit, [anons], site_id, brand_id, no_buy, article,"
                
."hit, new, action, is_file, [measure_unit] FROM {shop} "
                
." WHERE [act]='1' AND trash='0' AND id IN (".implode(",", $productsId).")");

    
$this->elements($this->result["rows"]);

    foreach (
$this->result["rows"] as &$row)
    {
            
$this->format_data_element($row);
    }

    return
$this->result;
}

6) Добавляем шаблонную функцию в modules\shop\shop.php

/**
* Шаблонная функция: выводит результаты поиска через Sphinx
* @return void
*/
public function show_sphinx_search_result()
{
    if(!empty(
$_GET['searchword'])){
        
$searchword = strip_tags($_GET['searchword']);
        
$searchword = htmlspecialchars($searchword);                
        
$result = $this->model->show_sphinx_result($searchword);
        
$result['searchword'] = $searchword;
        echo
$this->diafan->_tpl->get('show_sphinx_search_result', 'shop', $result);
    }
    else{
        
$result = array();
        
$result['error'] = 'Ошибка: не задано слово для поиска.';
        echo
$this->diafan->_tpl->get('show_sphinx_search_result', 'shop', $result);
    }
}
Автор решения: Захар (chezter)