15 июня 2009 г. PHP Wordpress Windows SphinxSearch FreeBSD Поисковые системы

Sphinx. Установка, настройка и использование поискового движка

sphinx

Не так давно, я написал статью "FreeBSD. Установка и настройка Яндекс.Сервер" и пообещал в комментариях рассказать про поисковый движок Sphinx. Это одна из трех запланированных статей про этот замечательный поисковый движок, в следующих статьях расскажу про расширение для PHP и расширение для MySQL.

Операционная система, в которой будем производить установку и настройки - FreeBSD, но так же буду давать советы и для Windows-пользователей.

В качестве примера, будем разрабатывать поиск для моего блога на Wordpress. Для самых не терпеливых, вот демонстрация работы поисковика http://demo.adw0rd.ru/sphinxsearch/.

Установка

Установка достаточно простая

# cd /usr/ports/textproc/sphinxsearch
# make config

Выбираем:

  • "mysql", если вы пользуетесь данной СУБД и хотите работать с данными непосредственно из Sphinx
  • "iconv" для поддержки разных кодировок
# make install

Вот и все, установка завершена!

Скачать исходники и Windows-версии можно тут: http://sphinxsearch.com/downloads.html.

После скачки Windows-версии, достаточно распаковать архив и указать в системной переменной "Path" полный путь до каталога \sphinx\bin.

Настройка

До начала поиска надо проиндексировать вашу информацию, создадим наш конфигурационный файл и укажем что и как индексировать, а также как отдавать результаты поиска.

Создадим конфигурационный файл для нашего поиска по блогу /home/sphinx/sphinx.conf:

source adw0rd_wp
{
        # Параметры подключения к БД
        type = mysql
        sql_host = localhost
        sql_user = user
        sql_pass = password
        sql_db = database_name
        sql_port = 3306

        # Установим кодировку для работы с БД
        sql_query_pre = SET NAMES utf8
        sql_query_pre = SET CHARACTER SET utf8

        # Запрос выборки данных для индексации
        sql_query = SELECT ID as post_id, post_title, post_content FROM wp_posts WHERE post_type = 'post'

        # Запрос доп. информации для вывода результата (используется утилитой "search")
        sql_query_info = SELECT * FROM wp_posts WHERE ID = $id

        # Время простоя (sleep) перед посылкой запросов серверу (предназначен для разгрузки сервера БД)
        # Если установите "= 1000", то засыпание будет длится 1 секунду
        sql_ranged_throttle = 0
}

index adw0rd_wp
{
        # Использовать соответствующий source-блок настроек при индексации
        source = adw0rd_wp

        # Путь до файлов индекса
        path = /home/sphinx/data/adw0rd_wp

        # Способ хранения индекса (none, inline, extern)
        # Подробнее http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-docinfo
        docinfo = extern

        # Memory lock (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-mlock)
        mlock = 0

        # Использование английского и русского стемминга
        morphology = stem_enru

        # Минимальная длина индексируемого слова
        min_word_len = 2

        # Установка используемой кодировки
        charset_type = utf-8

        # Таблица символов (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-charset-table)
        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

        # Использовать оператор усечения "*" (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-enable-star)
        enable_star = 1
}

indexer
{
        # Максимальный лимит используемой памяти RAM
        mem_limit = 32M
}

searchd
{
        # Адрес сервера
        address = 127.0.0.1

        # Порт
        port = 3312

        # Лог
        log = /home/sphinx/log/searchd.log

        # Лог запросов
        query_log = /home/sphinx/log/query.log

        # Таймаут на соединение с сервером (в секундах). При истечении времени происходит обрыв
        read_timeout = 5

        # Максимальное кол-во потомков от процесса
        max_children = 30

        # Путь до pid-файла
        pid_file = /home/sphinx/log/searchd.pid

        # Максимальное кол-во результатов выдачи
        max_matches = 1000
}
В новых версиях SphinxSearch надо использовать:
listen = 127.0.0.1:3312


Вместо
# Адрес сервера
address = 127.0.0.1

# Порт
port = 3312

Полная документация: http://www.sphinxsearch.com/docs/.

Разберем используемые нами SQL-запросы:

# Запрос выборки данных для индексации
sql_query = SELECT post_title, post_content FROM wp_posts WHERE post_type = 'post'

Тут мы выбираем заголовки и содержимое статей таблицы постов блога, при этом надо указать что типа поста - "post" (это та самая версия поста, которая считается опубликованной и текущей, так как есть еще ревизионные подверсии постов).


# Запрос доп. информации для вывода результата (используется утилитой "search")
sql_query_info = SELECT * FROM `wp_posts` WHERE `ID` = $id

Этот запрос применяется для вывода дополнительных данных результатов поиска используемый утилитой коммандной строки "search".

Индексация

Укажем в качестве конфига созданный нами конфигурационный файл:

# indexer --config /home/sphinx/sphinx.conf --all

Для обновления текущего индекса используйте "--rotate", он добавит к созданному индексу новые данные, а измененные соответственно изменит.

# indexer --config /home/sphinx/sphinx.conf --rotate

P.S. Если индексация не удалась, пишите комментарии к статье, посмотрим что случилось... :)

Использование поиска

Для поиска в консоли есть утилита "search":

# search --config /home/sphinx/sphinx.conf искомая комбинация

Запуск поискового сервера

Для работы с поисковым сервером, нам надо его запустить:

# searchd --config /home/sphinx/sphinx.conf

Далее, мы сможем использовать Sphinx API.

Использование Sphinx API для PHP

Для работы со Sphinx API необходимо подключить файл sphinxapi.php, вы можете найти эту библиотеку в поставке с дистрибутивом. Например для установки из портов FreeBSD - путь "/usr/ports/textproc/sphinxsearch/work/sphinx-0.9.8.1/api/sphinxapi.php", а для Windows - "sphinx\api\sphinxapi.php".

А теперь напишем скрипт для работы с проиндексируемыми данными поисковика, то есть для запросов искомых слов и вывода результатов поиска!

<html>
<head>
    <meta content="text/html; charset=utf-8" http-equiv="Content-Type"/>
    <title>Sphinx search for Wordpress</title>
</head>
<body>

<form action="" method="get">
    <input name="s" size="40" value="<?php echo @$_GET['s'];?>" />
    <input type="submit" value="Искать!" />
</form>
<?php

if(isset($_GET['s']) and strlen($_GET['s']) > 2) {

    // Подключаем sphinx-api
    require_once ("sphinxapi.php");

    // Искомая комбинация
    $string = $_GET['s'];

    // Создаем объект клиента для Sphinx API
    $sphinx = new SphinxClient();

    // Подсоединяемся к Sphinx-серверу
    $sphinx->SetServer('localhost', 3312);

    // Совпадение по любому слову
    $sphinx->SetMatchMode(SPH_MATCH_ANY);

    // Результаты сортировать по релевантности
    $sphinx->SetSortMode(SPH_SORT_RELEVANCE);

    // Задаем полям веса (для подсчета релевантности)
    $sphinx->SetFieldWeights(array ('post_title' => 20, 'post_content' => 10));

    // Результат по запросу (* - использование всех индексов)
    $result = $sphinx->Query($string, '*');

    // Если есть результаты поиска, то
    if ($result && isset($result['matches']))
    {

        // Соединяемся с БД
        mysql_connect('localhost', 'user', 'password');
        mysql_select_db('adw0rd_wp');

        // Устанавливаем кодировки
        mysql_query('SET NAMES utf8');
        mysql_query('SET CHARACTER SET utf8');

        // Получаем массив ID постов блога
        $ids = array_keys($result['matches']);

        // Выводим посты отсортированные по релевантности
        $id_list = implode(',', $ids);
        $sql = '
            SELECT `ID`, `post_title`, `post_content`
                FROM `wp_posts`
                WHERE `ID` IN ('.$id_list.')
                ORDER BY FIELD(`ID`, '.$id_list.')';

        $resource = mysql_query($sql);

        // Выводим результаты поиска
        echo '<ol>';
        while ($result = mysql_fetch_assoc($resource)) {
            echo '<li><span><a href="/?p='.$result['ID'].'">'.$result['post_title'].'</a></span><div>'.mb_substr(htmlspecialchars($result['post_content']), 0, 400).'</div>';
        }
        echo '</ol>';
    }
}
?>
</body>
</html>

Документация по Sphinx API для PHP: http://www.sphinxsearch.com/wiki/doku.php?id=php_api_docs

Резюме

За короткое время нам удалось развернуть быстрейший "поисковый сервис своими руками", с возможностями полнотекстового поиска. Демонстрация работы: http://demo.adw0rd.ru/sphinxsearch/.

По всем вопросам, касающемся этой статьи пишите в комментарии.

P.S. Если вам не знакомы слова: "стемминг", "инфикс", "словоформа" и т.д., то существует проект Википедия, в которой можно с легкостью об этом узнать!

Комментарии

ужас.... так то это, столько слов а на деле все за пару минут поднимается)) сфинкс акуенен

привет! пытаюсь поднять под windows xp. Так вот, я хочу попробывать поиск по базе, которая дается в качестве примера, где уже все настроенно. Там еще есть файл с SQL запросом, который создает таблицу documents и заполняет ее данными. Так вот при поиске через search я ввожу такую команду:

search test

а оно выдает:

using config file './sphinx.conf'...
index 'test1': search error: failed to open data/test1.sph: No such file or directory.

что это за файл? и почему test1, я же написал просто test?

А ты как индексировал? И какой у тебя путь до конфига получился?

Имхо намного пижже, чем Яндекс-сервер! Убедился на личном опыте)

А заказ на поднятие сфинкса для сайта возьмешь?

Zona, согласен, мне тоже больше нравится :)

aktuba, для какого сайта?
Свой сервер? Виртуальный?
Какой бюджет?

пиши на x11org@gmail.com

adw0rd: свои сервера, сайт nnm.ru =). Бюджет - хотелось бы у тебя услышать.

путь к конфигу у меня получился "c:\Program Files\sphinx\bin\sphinx.conf". И еще такой вопрос. Я пытаюсь выполнить индексацию. Делаю так:

C:\Program Files\sphinx\bin>indexer --all
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
using config file './sphinx.conf'...
indexing index 'test1'...
collected 4 docs, 0.0 MB
sorted 0.0 Mhits, 100.0% done
total 4 docs, 193 bytes
total 0.152 sec, 1267.04 bytes/sec, 26.26 docs/sec
indexing index 'test1stemmed'...
FATAL: failed to open @CONFDIR@/data/test1stemmed.spl: No such file or directory, will not index. Try --rotate option.

в чем проблема? И как выставить @CONFDIR@ ? Где она прописывается?

aktuba, бюджет зависит от кол-ва данных и структуры поиска, я еще не могу представить это, без малейшего ТЗ. Но я заинтересован :)

А почему бы видео не записать как что делалось, небыло бы вопросов?

adw0rd: постучи в аську, plz: 255261508

У меня аськи нет :( http://adw0rd.ru/contacts

Если у тебя нет скайпа и жаббера, то могу в принципе восстановить аську

Есть скайп: aktuba. Есть и куча жабберов, но я ими не пользуюсь. Можешь добавить aktuba@qip.ru, но не обещаю, что контакт сохранится =)

aktuba, добавил тебя в скайпе и в жаббер :)

smackthat, укажи полный путь до каталога "/data/", там хранятся индексы. У меня в конфиге написано как это делать, ты читал внимательно?

шас еще раз прочту

smackthat, видео можно, сегодня попробую снять, но не обещаю :)
Может при следующих выпусках сниму...

разобрался, ищет через утилиту search. Вот осталось через php попробовать. А видео было б воопще клево!

Вот осталось через php попробовать.
ну попробуй по соей статье заюзать API :)

в общем попробывал, но страничка зависает, непойму почему. Делаю так:


    function search($search)
    {

    // Подключаем sphinx-api (я использую CodeIgniter)
     $this->load->library('sphinx');

     $this->sphinx->SetArrayResult(TRUE);
     $result = $this->sphinx->Query($search);

     return $result;        
    }  

Просто как будто загружается, но ничего не происходит, что это может быть?

также попробывал через обычный php, без фреймворка. Точно как у тебя в примере. таже ситуация - страничка подвисает. Проверил сервисы - SphinxSearch есть. Но при его ручном запуске выдает ошибку - Cant start service on local machine

теперь запустил через консоль сам демон и оно выдало такое:
This program (CLI search) is for testing and debugging purposes only;
it is NOT intended for production use.
C:\Program Files\sphinx\bin>searchd
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
WARNING: forcing --console mode on Windows
using config file './sphinx.conf'...
creating server socket on 127.0.0.1:3312
accepting connections

// в этом месте была значительная пауза

caught SIGTERM, shutting down
shutdown complete

Дай полностью свой конфиг

#############################################################################
## data source definition
#############################################################################

source articles
{
        # Параметры подключения к БД
        type = mysql
        sql_host = localhost
        sql_user = root
        sql_pass = *********
        sql_db = testdatabase
        sql_port = 3306

        # Установим кодировку для работы с БД
        sql_query_pre = SET NAMES utf8
        sql_query_pre = SET CHARACTER SET utf8

        # Запрос выборки данных для индексации
        sql_query = SELECT id, title, category, description, key_words, short_text, id_author FROM articles

        # Запрос доп. информации для вывода результата (используется утилитой "search")
        sql_query_info = SELECT * FROM articles WHERE `id` = $id

        # Время простоя (sleep) перед посылкой запросов серверу (предназначен для разгрузки сервера БД)
        # Если установите "= 1000", то засыпание будет длится 1 секунду
        sql_ranged_throttle = 0
}



#############################################################################
## index definition
#############################################################################

index articles
{
        # Использовать соответствующий source-блок настроек при индексации
        source = articles

        # Путь до файлов индекса
        path = c:\Program Files\sphinx\bin\data\articles

        # Способ хранения индекса (none, inline, extern)
        # Подробнее http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-docinfo
        docinfo = extern

        # Memory lock (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-mlock)
        mlock = 0

        # Использование английского и русского стемминга
        morphology = stem_enru

        # Минимальная длина индексируемого слова
        min_word_len = 2

        # Установка используемой кодировки
        charset_type = utf-8

        # Таблица символов (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-charset-table)
        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

        # Использовать оператор усечения "*" (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-enable-star)
        enable_star = 1
}

#############################################################################
## indexer settings
#############################################################################

indexer
{

    mem_limit           = 32M

}

#############################################################################
## searchd settings
#############################################################################

searchd
{
        # Адрес сервера
        address = 127.0.0.1

        # Порт
        port = 3312

        # Лог
        log = c:\Program Files\sphinx\log\searchd.log

        # Лог запросов
        query_log = c:\Program Files\sphinx\log\query.log

        # Таймаут на соединение с сервером (в секундах). При истечении времени происходит обрыв
        read_timeout = 5

        # Максимальное кол-во потомков от процесса
        max_children = 30

        # Путь до pid-файла
        pid_file = c:\Program Files\sphinx\log\searchd.pid

        # Максимальное кол-во результатов выдачи
        max_matches = 1000
}


# --eof--

а это нормально что порты не совпадают?
source articles
{
sql_port = 3306
}

searchd
{
port = 3312
}

smackthat, первый порт - SQL, второй - Sphinx

ясно. А в чем проблема не знаешь? В переменную Path добавил путь к папке bin, но не пашет.

В переменную Path добавил путь к папке bin, но не пашет.
Прописать патх нужно для вызова search, searchd, indexer, без прописывания полного пути...

Сейчас посмотрю конфиг...

>Прописать патх нужно для вызова search, searchd, indexer, без прописывания полного
>пути...
а вот оно что))) не силен я в этих консольных штуках...

>Сейчас посмотрю конфиг...
жду)))

smackthat, а ты создал каталог "c:\Program Files\sphinx\bin\data"?

да, и после индексации в нем появились файлы articles с разными форматами sp*

smackthat, проверял работу SQL-запросов? Я просто протестил с твоими конфигами, все нормально!

Ты так в точности запускаешь? Если нет, покажи как именно.


# indexer --config c:\Program Files\sphinx\sphinx.conf --all
# search –-config c:\Program Files\sphinx\sphinx.conf искомая комбинация
# searchd –-config c:\Program Files\sphinx\sphinx.conf

C:\Program Files\sphinx\bin>indexer --config "C:\Program Files\sphinx\sphinx.conf" --all
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
using config file 'C:\Program Files\sphinx\sphinx.conf'...
indexing index 'articles'...
collected 8 docs, 0.0 MB
sorted 0.0 Mhits, 97.8% done
total 8 docs, 9135 bytes
total 0.949 sec, 9630.17 bytes/sec, 8.43 docs/sec

C:\Program Files\sphinx\bin>search --config "C:\Program Files\sphinx\sphinx.conf" qip
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
using config file 'C:\Program Files\sphinx\sphinx.conf'...
index 'articles': query 'qip ': returned 1 matches of 1 total in 0.000 sec
displaying matches:
1. document=82, weight=3
        id=82
        title=21 QIPxyZ ????????? ???? ??? ??????
        category=35
        type=1
        language=1
        description=QIP ????????? ???? ????
        key_words=qip, icq, internet, ?????, ?????
        short_text=? ????????? ??? ??????? ?????? ?? ??????? Mblogi (?????????? ?? QIP, ? ??????? ?? ????????? ??????????? ??????? ????????????? QIP Infium).

и еще там текст, в общем ищет


C:\Program Files\sphinx\bin>searchd --config "c:\Program Files\sphinx\sphinx.conf"
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff
FATAL: malformed or unknown option near 'Ц-config'; use '-h' or '--help' to see available options.
C:\Program Files\sphinx\bin>

теперь другой результат, так как раньше конфиг был в папке bin. Что делать?

FATAL: malformed or unknown option near 'Ц-config';
Что за "Ц-config"? Чего там "Ц" делает?

теперь другой результат, так как раньше конфиг был в папке bin
А причем тут папка "bin"?

adw0rd, так держать! Еще один замечательный программерско-админский пост!

это просто случайно скопировал, считай что последней строки нет. А можно как-то деинсталировать сервис, а потом повторно установить?

smackthat,

searchd --config c:\Webserver\usr\sphinx\sphinx.conf --stop

Snowcore, спасибо! :)

при попытке остановить пишет что pid файл недоступен или нечитаем. Хотя я и создал каталог, в котором он должен быть. В чем проблема? Также создавал этот пид файл (просто новый пустой файл с этим названием) пишет, что невалидный пид файл. Где его брать? При попытке проинсталировать (--install) пишет что сервис уже запущен.

PID не надо создавать, у меня он вообще не создается. *.pid - это Файл, в который сохраняется PID-процесса.

Спасибо за статью и пояснения я разобрался!

Ура! :)

А что за ошибка при индексации - column '1' has no name ?
Ошибка из-за строки

sql_query = SELECT id as news_id, topic, date FROM news

работает только если выбираем одно поле as его новое имя, типа

sql_query = SELECT id as news_id FROM news

Почему же не обрабатывает нормальный запрос?

splash, покажите source полнстью

source adw0rd_wp
{
        type = mysql
        sql_host = localhost
        sql_user = user
        sql_pass = pass
        sql_db = _mpc
        sql_port = 3306
        sql_query_pre = SET NAMES utf8
        sql_query_pre = SET CHARACTER SET utf8
        sql_query = SELECT id as news_id, topic, date FROM news
        sql_query_info = SELECT * FROM news WHERE id = $id
        sql_ranged_throttle = 0
}

Какая версия sphinx и mysql у вас? Только точнее, пожалуйста.

sphinx-0.9.8.1-win32
mysql 5.1.31
база в utf8

Думаю проблема с Win-версией, я под Windows не устанавливал Sphinx.
Посмотрите http://sphinxsearch.com/forum/view.html?id=937

Это я уже видел, но не могу найти библиотеку libmysql.dll от mysql 5.0.xx отдельно от дистриба общего...

http://dev.mysql.com/get/Downloads/MySQL-5.0/mysql-noinstall-5.0.83-win32.zip/from/http://gd.tuwien.ac.at/db/mysql/ разве тут вы не нашли?

Слишком огромный архив выкачивать ради одной dll...
Библиотеку нашёл, через exe всё работает, но при запуске через php выполняются следующие строки


$string = $_POST['s'];// Искомая комбинация
$sphinx = new SphinxClient();// Создаем объект клиента для Sphinx API
$sphinx->SetServer('localhost', 3312);// Подсоединяемся к Sphinx-серверу
$sphinx->SetMatchMode(SPH_MATCH_ANY);// Совпадение по любому слову
$sphinx->SetSortMode(SPH_SORT_RELEVANCE);// Результаты сортировать по релевантности
$sphinx->SetFieldWeights(array ('NAME' => 20, 'DESC_FULL' => 10));
echo '1';
$result = $sphinx->Query($string, '*');
echo '2';

на последней строке повисает минуты на 2 и без каких-либо ошибок и сообщений завершает работу, '1' выводится, '2' - нет.
Может из-за той же библиотеки, подменяю libmysql.dll в папке mysql - ничего не меняется, может нужна php_mysql.dll от старой версии...

splash, у меня этот архив качается 2 минуты. Вот ваша библиотека: http://1dfile.ru/get/2c5b91fca2ce752759aea959c3c08d03/libmysql.dll

может нужна php_mysql.dll от старой версии...
Вряд ли.

Спасибо за ссылку, но у меня такая же dll.
В общем всё решилось, глючил searchd, повисал при запуске, хотя висело окно с надписью ожидаю подключений... перегрузил всё что можно - заработало.
И библиотека вообще не при чём, при поиске через php она не используется.

И библиотека вообще не при чём, при поиске через php она не используется.
mysql-php-api ее не юзает?

Так теперь у вас все работает?

Да, спасибо!
Дело осталось за тестированием...

Объясните мне пожалуйста, что это за запросы???

# Запрос выборки данных для индексации
        sql_query = SELECT ID as post_id, post_title, post_content FROM wp_posts WHERE post_type = 'post'

        # Запрос доп. информации для вывода результата (используется утилитой "search")
        sql_query_info = SELECT * FROM wp_posts WHERE ID = $id

а точнее, что это за post откуда он его берет и что это за $id как оно туда приходит... откуда, допустим я хочу сделать запрос по "той же базе и настройках" как и тут

запрос который я хочу сделать -> SELECT id, title, category FROM articles where title = 'хочу найти...'

как я понимаю этот запрос нужно положить именно в конфиг сфинкса, а в то место 'хочу найти...' подставить переменную и когда я напишу что-то типа $result = $sphinx->Query($string, '*'); оно подставит эту $string сюда -> 'хочу найти...' и вернет результат в id а дальше уже по мускулу подставляю те id и возвращаю то, что мне нужно... так как его туда подставить эту переменную $string именно сюда 'хочу найти...' вообщем на этом моменте я чет не догоню...

Александр, вы немного не правильно понимаете.

sql_query = SELECT ID as post_id, post_title, post_content FROM wp_posts WHERE post_type = 'post'

Это mysql-выборка, которая будет проиндексирована сфинксом, то есть те данные по которым он будет искать. "SELECT ID as post_id" - это будет ид для сфинкса и именно он используется в запросе:

sql_query_info = SELECT * FROM wp_posts WHERE ID = $id

попытка номер два...


# Запрос №1
        sql_query = SELECT id, title, category, description, key_words, short_text, id_author FROM articles

# Запрос №2
        sql_query_info = SELECT * FROM articles WHERE `id` = $id

первый запрос ничего не делает кроме того как извлекает ВСЕ данные с таблицы и сохраняет сюда его path = /home/sphinx/data/adw0rd_wp как индекс

запрос номер два а именно $id и есть это $result = $sphinx->Query($string, '*');

т.е. $string подставляется в $id и он по полю id ищет ту строку $string?

или опять не так? блин в сайте сфинкса вообще такой бред ни одного дельного примера, на вашем блоге единственный толковый пример по работе с сфинксом во всем инете кажись и то на такой мелочи я торможу


# Запрос доп. информации для вывода результата (используется утилитой "search")
sql_query_info = SELECT * FROM wp_posts WHERE ID = $id

обратите внимание на коммент, "второй" запрос используется ТОЛЬКО утилитой search, а не API.

API только тянет иды, далее вы сами разруливаете что с ними делать, если хотите всетаки работать непосредственно в mysql, то почитайте мою статью о SphinxSE

У меня какая-то странная ошибка, когда пытаюсь запустить индексацию:

ERROR: invalid token in C:\sphinx\sphinx.conf line 1 col 1.
FATAL: failed to parse config file 'C:\sphinx\sphinx.conf'.

Snowcore, а, это ты :) Не узнал, но всеравно ответил в жаббер )

Еще хотелось бы увидеть пример подсветки результатов поиска, используя метод BuildExcerpts

Snowcore, в мане же отличный пример O_o

Привет, никак не могу справиться с проблемой. При установке поиск работал прекрасно и первое индексирование прошло успешно. Сейчас переехали на новый сервер перенесли полностью всё, поиск работает, а вот запустить индексирование никак не удается. Не подскажете, в чём может быть дело?

$ indexer --config /var/www/pro/config/sphinx.conf --all --rotate
Sphinx 0.9.9-rc2 (r1785)

using config file '/var/www/pro/config/sphinx.conf'...
WARNING: key 'port' is deprecated in /var/www/pro/config/sphinx.conf line 343; use 'listen' instead.
indexing index 'baseIndex'...
ERROR: index 'baseIndex': no valid sources configured; skipping.
indexing index 'news'...
FATAL: failed to open /var/www/pro/tmp/searchindex/news.tmp.spl: No such file or directory, will not index. Try --rotate option.

В версии 0.9.9 поменялись конфиги, надо теперь не


address = 192.168.0.1
port = 3312

а


listen = 192.168.0.1:3312

О чем вас и предупреждает SphinxSearch - "use 'listen' instead."

А такой вопрос есть ли возможность прикрутить поисковичек сфинкс к торрент трекеру??
Если да то не подскажеш как, а тот тот поисковичек который идет в "комплекте" гадость редкосная.

Можно, индексируете данные, выводите результаты. В чем конкретно проблема? В каком виде данные по которым осуществляется поиск?

Спасибо за статью! Все настроил, работает.

adw0rd: А возможно выводить результат напрямую из Sphinx, а не делая доп. запрос к мускулю, ведь в консоли мы получаем эти данные, а при посте формы нет.

ingvar, sphinx использует эти данные только для поиска по ним. Вы не можете их использовать в качестве результата, а то что вы их видите в консоли это тоже результаты из mysql

Посмотрите внимательно свой конфиг:


        # Запрос доп. информации для вывода результата (используется утилитой "search")
        sql_query_info = SELECT * FROM wp_posts WHERE ID = $id

Теперь все ясно. А Морфология, для неё разве не нужны словари? У sphinx я не увидел их.

Обратите внимание на конфиг, там есть:


        # Использование английского и русского стемминга
        morphology = stem_enru

Подробнее: http://sphinxsearch.com/docs/manual-0.9.8.html#conf-morphology

А как можно прикрутить его на CentOS 5.4, и сделать так чтобы он индексировал и искал если написал не кирилицеа а аглийским(розкладку не выключил)?
Если да то можно узнать личными заказами занимаешся???))

и есть ли какаято типа админка?? чтобы показовать что индексировать

и торрент он точно сможет проиндексировать??? а то пробовали через другие поисковички так оно только ихенею выдавало

А как можно прикрутить его на CentOS 5.4
А какие проблемы?
и сделать так чтобы он индексировал и искал если написал не кирилицеа а аглийским(розкладку не выключил)?
я понял о чем вы, но про такую возможность не знаю, и она слабо относится к задачам поисковика, это надо делать через свои скрипты, имхо
Если да то можно узнать личными заказами занимаешся???))
Уже нет, времени нет.
и есть ли какаято типа админка?? чтобы показовать что индексировать
нет, есть консоль
и торрент он точно сможет проиндексировать??? а то пробовали через другие поисковички так оно только ихенею выдавало

что подразумевается под индексированием торрента?

Хочу сделать поисковик по страницам своего торрента. Стандартный немного не устраивает

hellwarr, ясно, вам надо не по торрентам искать, а по вашему сайту... Я не работал с готовыми движками для торрент-трекеров, мы только свой разрабатывали с нуля http://kinsburg.ru/

Хотелось бы такую же статейку, только для индексации сторонних сайтов, тоесть расположенных на отдельных серверах и без доступа к их БД. Тоесть как это делают всякие там яндексы с гуглами.

  1. Написать паука
  2. Индексатором обработать инфу

Хотя статью можно накатать...

О какм пауке речь?
Статью обязательно надо. Ибо не у всех все сайты на одном хосте, может и не ко всем есть доступ, а я для локалки поисковик решил сделать. Тамошние сайты не все доступны из интернета и не у всех пользователей есть инет(как ни удивительно).

О какм пауке речь?
Речь о пауке, написанном на каком-либо языке программирования, занимающимся тем, что ходит по заданным сайтам и собирает информацию с них.

Тоесть ты говоришь об индексаторе? А что, в нормальный пакет не должна включаться хоть какая-то реализация под несколько наборов задач?
В том же яндекс.сервере всё в один пакет собрано и индексатор, и поисковик, и даже веб сервер =)

alpha_Qu4z4r,
1. Я говорю о поисковом пауке, индексатор это другое.
2. Sphinx - FTS движок. Никакого отношения к сбору данных он не должен иметь.
3. Я не знаю есть ли для Sphinx готовые реализации поискового паука, и меня это не интересовало до этого времени. Но если бы мне понадобился паук, то я бы его сам написал.

Понятно, значит яндек.сервер для такой задачи подходит как никто другой... А я надеялся на альтернативы не в виде кубика-рубика =)

Подскажите, пожалуйста, конфиг для индексации одной файловой директории и нескольких БД (под управлением Interbase).

Я не знаю, посмотри оф. документацию

ERROR: invalid token in C:\sphinx\sphinx.conf line 1 col 1.

FATAL: failed to parse config file 'C:\sphinx\sphinx.conf'.

У меня тоже такая ошибка, подскажите в чем дело, плиз

Какая кодировка файла? Случайно не UTF8?
И что у вас на первой строке файла? (всю строку)

Спасибо, я уже разобрался. Редактор сохранял файл save with bom. сохранил без, все заработало.
Спасибо большое за статью

Ага, и я об этом :)

Мне нужен простейший поиск по коротким статьям. На данный момент при помощи match against время поиска 0,17-2 сек, но надо быстрее. Сфинкс в данном вопросе поможет?

Да, уверен что поможет

В принципе помогло, ищет моментально, но возникла старая непобежденная проблема:
сфинкс возвращает айдишники, далее эти айдишники я ищу в базе, и получаю те же самые 0,25 сек.
Или же, в данном случае сфинкс не причем, запрос вида select * from table limit 85300,30 может выполняться до 10 сек.
Как это побороть?

сфинкс конечно не причем, он вам нашел результаты быстро, на этом его миссия окончена. А далее, как вы производите выборку средствами mysql - отдельный вопрос. Кстати, вы юзаете Sphinx API, SphinxSE или SphinxQL?

Конечно же не причем, "или же" - это ссылка на другую ситуацию.
Юзаю через апи. sphinxql не заработал.
А вот что нашел по моей проблеме:

Но если количество записей велико, и нужно выполнить запрос SELECT ... FROM table LIMIT 1000000, 1000020 то для выполнения такого запроса MySQL сначала выберет 1000020 записей, отбросит первый миллион и вернет 20. Это может быть вовсе не быстро. Тривиальных путей решения проблемы нет. Многие просто ограничивают количество доступных страниц разумным числом. Также можно ускорить подобные запросы использованием покрывающих индексов или сторонних решений (например, sphinx).

Я немного не понял, вы сфинкс юзаете для поиска или для выборки?

Если речь о таком запросе:

SELECT ... FROM table LIMIT 1000000, 1000020 

то я бы сделал так:

SELECT ... FROM table WHERE id > 1000000 and id < 1000020 

Что-то в этом духе, можно еще что-то придумать...

http://habrahabr.ru/blogs/mysql/76861/ вот почитайте по поводу MySQL

Да. Этот пример видел. Тут сложность у меня с внедрением, так как limit идет из сложного условия из нескольких таблиц, то надо сделать несколько запросов, чтобы узнать id'ки. А далее придется сделать на выборку where id in ().
Если в сфинксе создать несколько идексов, то как можно обратиться к конкретному из php api?

Если такое вообще возмножно


    // Результат по запросу (* - использование всех индексов)
    $result = $sphinx->Query($string, '*');

Вместо "*" поставьте свой индекс.

Спасибо. Теперь мне стала понятна структура конф файлов и для чего там столько разделов.

adw0rd, установил sphinx с помощь вашей статьи.

Делаю поиск в консоли (слово 'test' в базе есть).

search test

Sphinx 0.9.9-release (r2117)
Copyright (c) 2001-2009, Andrew Aksyonoff

using config file '/usr/local/etc/sphinx.conf'...
index 'tovar': query 'test ': returned 1 matches of 1 total in 0.000 sec

displaying matches:
1. document=8, weight=1
id=8
id_autor=1
id_firm=102249
id_catalog=87101
odobr=1
name=
opis=test
price=
date_create=0

words:
1. 'test': 1 documents, 1 hits

Но из php не работает

require_once '/usr/local/etc/sphinx/sphinx/api/sphinxapi.php';
$client = new SphinxClient();

$client->SetLimits(1,10);
$client->SetArrayResult(true);
$result = $client->Query('test','*');
echo '<pre>';
print_r($result);
echo '</pre>';

А где?

    // Подсоединяемся к Sphinx-серверу
    $sphinx->SetServer('localhost', 3312);

Эта строчка была, потом я ее убрал. Все варианты попробовал. Не работает и не могу понять в чем причина.


 <?php


  include "/usr/local/etc/sphinx/sphinx/api/sphinxapi.php";
  $cl = new SphinxClient();
  $cl->SetServer('localhost', 3312);
  $cl->SetMatchMode(SPH_MATCH_EXTENDED2);
  $results = $cl->Query('test', 'tovar');
  print_r($results);

  ?>


   </body>
   </html>

Дайте адрес сервера, где у вас установлен сфинкс, я проверю.
Вот мои контакты если что http://adw0rd.ru/contacts/

зы. Вы searchd то подняли? Утилита search не использует этот демон, а API использует.

searchd я запускал перед использованием в php, скинул root вам на почту.

Был неверно указан порт, надо:

$cl->SetServer('localhost', 9312);

Благодарствую за помощь!. Действительно работает.

С наступающим Новым Годом! Всего наилучшего!

Не подскажете как сделать индекс по точному вхождению фразы. К примеру если категория называется "очень большие грузовики", то она не должна найтись по слову "очень" или "грузовики".
т.е. надо чтобы сфинкс также учитывал пробелы.

по английски ищет а по русски не хочет
Вот мой конфиг

source zizl
{
        type = mysql
        sql_host = localhost
        sql_user = root
        sql_pass = 
        sql_db = zizl
        sql_port = 3306

        sql_query_pre = SET NAMES utf8
        sql_query_pre = SET CHARACTER SET utf8

        sql_query = SELECT m.id_message, m.rendered, u.username FROM messages m LEFT JOIN users u ON m.id_user = u.id_user 

        sql_query_info = SELECT * FROM messages WHERE `id_message` = $id
        sql_ranged_throttle = 0
}

index message
{
        source = zizl
        path = S:/sphinx/index/message
        docinfo = extern
        mlock = 0
        morphology = stem_enru
        min_word_len = 2
        charset_type = sbcs
        #charset_table = 0..9, A..Z->a..z, _, a..z, U+A8->U+B8, U+B8, U+C0..U+DF->U+E0..U+FF, U+E0..U+FF
        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
}

indexer
{
        mem_limit = 32M
}

searchd
{
        address = 127.0.0.1
        port = 3312
        log = S:/sphinx/log/searchd.log
        query_log = S:/sphinx/log/query.log
        read_timeout = 5
        max_children = 30
        pid_file = S:/sphinx/log/searchd.pid
        max_matches = 1000

}

olegre,

charset_type = sbcs
это что за кодировка?
        sql_query_pre = SET NAMES utf8
sql_query_pre = SET CHARACTER SET utf8
а тут вы юзаете utf-8

Понимаете в чем смысл?

Ad1ce, хороший вопрос, сам не знаю... но дело не в индексе, а в самом поиске. Попробуйте поменять match_mode (all, any, both, ext...)

adw0rd,

кодировку я поменял, но проблема осталась.

S:\sphinx\bin>search дело
Sphinx 0.9.8-release (r1533)
Copyright (c) 2001-2008, Andrew Aksyonoff

using config file './sphinx.conf'...
index 'message': query 'фхыю ': returned 0 matches of 0 total in 0.000 sec

words:

обратите внемание на кодировку вместо 'дело' написано 'фхыю '

Вы в Windows-консоли это все пишете? Так у вас кодировка будет cp866 скорее всего, а не utf8, погуглите на тему как установить в консоле кодировку utf8

Настраиваю поиск, но также столкнулся с проблемой поиска по кириллице.
Структура таблицы новостей:

CREATE TABLE IF NOT EXISTS `News` (
  `id` int(12) unsigned NOT NULL auto_increment,
  `title` varchar(255) NOT NULL,
  `text` text NOT NULL,
  `publish` datetime NOT NULL,
  `f_year` int(4) NOT NULL,
  `f_month` int(2) NOT NULL,
  `f_day` int(2) NOT NULL,
  `url` varchar(255) NOT NULL,
  `member_id` int(12) NOT NULL,
  PRIMARY KEY  (`id`),
  KEY `publish` (`publish`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=119798 ;

Конфигурация Sphinx:

source news
{
        type = mysql
        sql_host = localhost
        sql_user = user
        sql_pass = password
        sql_db = database
        sql_port = 3306

        sql_query_pre = SET CHARACTER_SET_RESULTS=utf8
        sql_query_pre = SET NAMES utf8
        sql_query_pre = SET CHARACTER SET utf8

        sql_query = SELECT id `news_id`, title `news_title`, text `news_text` FROM News
        sql_query_info = SELECT * FROM News WHERE id = $id
        sql_ranged_throttle = 0
}

index news
{
        source = news
        path = /path/to/index/news
        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
        html_strip = 1
}

Индексация проходит нормально, без ошибок. Работаю в bash, кодировка utf8. Поиск по английскому слову хорошо работает, по русским словам, к
оторые присутствуют в базе неоднократно, возвращает нулевой результат:

#~/some/directory> search --config sphinx.conf лукас награда Sphinx 0.9.8.1-release (r1533) Copyright (c) 2001-2008, Andrew Aksyonoff using config file './sphinx.conf'... index 'news': query 'лукас награда ': returned 0 matches of 0 total in 0.000 sec words: 1. 'лукас': 0 documents, 0 hits 2. 'наград': 0 documents, 0 hits

В какую сторону копать с кодировками?

Все, разрешил проблему сам, но все равно спасибо.

Вот что смущает в примере Sphinx API для PHP

  // Результат по запросу (* - использование всех индексов)
    $result = $sphinx->Query($string, '*');

    // Если есть результаты поиска, то
    if ($result && isset($result['matches']))
    {

        // Соединяемся с БД
        mysql_connect('localhost', 'user', 'password');
        mysql_select_db('adw0rd_wp');

По сути производиться подключение к mysql, затем выборка

$sql = '
            SELECT `ID`, `post_title`, `post_content`
                FROM `wp_posts`
                WHERE `ID` IN ('.$id_list.')
                ORDER BY FIELD(`ID`, '.$id_list.')';

        $resource = mysql_query($sql);

В чем тогда смысл sphinx? Или я что-то не так понял?

Сфинкс быстро находит ключи, оооооочччень быстро, никакой mysql вам не даст такого качественного и быстрого полнотекстового поиска.

А если вас смущает использование API, то милости прошу: Sphinx SE и SphinxQL

Понятно, я просто думал что $result = $sphinx->Query($string, '*'); уже содержит результат.

Его так и используют все? Для выборки ключей sphinx, а для выборки значений mysql?

И еще такой вопрос а быть может sphinx и не так хорош, ведь yandex server
и postgeeSQL имеют словари, а не стемминг. Yandex server стоит на многих нагруженных проектах, http://company.yandex.ru/technology/server/clients/

adw0rd, у меня поиск возращает только 20 результатов (а если в phpmyadmin искать их гораздо больше), нигде в запросе LIMITS не писал. В чем может быть дело?

По умолчанию limit = 20, указывайте явно limit. И еще посмотрите сколько у вас выставлен в конфиге maxmatches.

maxmatches=1000
а limit в какую секцию писать?

Мне Яндекс.Сервер не понравился по ряду причин: громозкий, непредсказуемый, менее быстрый... короче мне он не понравился...

Sphinx - это удобная утилита. А Я.С - неудобный комбайн. Это мое ИМХО.

$sphinx->SetLimits(0,1000);

http://www.sphinxsearch.com/docs/manual-0.9.8.html#api-func-setlimits

Для выборки ключей sphinx, а для выборки значений mysql?

Человек задал вопрос. Присоединяюсь.

И зачем тогда это в конфиге:
sql_query_info = SELECT * from content WHERE r1.id=$id

Человек задал вопрос. Присоединяюсь.
Да, сфинкс для ключей, а где значение хранится ему всеравно. Поэтому надо тянуть с БД.
И зачем тогда это в конфиге: sql_query_info = SELECT * from content WHERE r1.id=$id

Я это уже объяснил в посте:

# Запрос доп. информации для вывода результата (используется утилитой "search")

adw0rd, бьюсь на вопросом, может вы подскажите, как сделать выделение найденого фрагмента, т.е. например,
я сделал запрос "продажа зерновых", а как мне отобразить слова справа и слева от запроса, т.е.

"""...Мы предлагаем ягромию, занимаемся оптовай "продажей зерновых" культур...."""

для того чтобы человек понимал почему этот результат был найден, как в сниппетах поисковых систем.

В Postgres-8.3 для этого есть функция ts_headline.
Ну и если исходим из того, что Свинкс только для выдачи ключей, то выдачу с подсветкой, на уровне БД сделаю примерно так:
select c.id,
ts_headline('russian', title, q) as title,
ts_headline('russian',descript,q) as descript,
FROM content AS c, to_tsquery('искомая фраза, которую загнали в Сфинкс') q
WHERE c.id=$ключ_полученный_от_сфинкс

adw0rd, Разжуй пожалуйста, как юзать штеммер из SphinxClient ?

Разобрался. Есть в сфинксе функция BuildExcerpts

На примере моего запроса (индексация полей в 2-х таблицах)

$sql = 'SELECT ws_cms_pub_firm.ID as ID, ws_cms_pub_firm.name as name, ws_cms_pub_firm.opis as opis, ws_cms_price_tab.opis as propisln, ws_cms_pub_firm.mail as mail, ws_cms_pub_firm.site as site, ws_cms_pub_firm.city as city FROM ws_cms_pub_firm, ws_cms_price_tab
  WHERE ws_cms_pub_firm.ID IN ('.$id_list.') AND ws_cms_price_tab.id_firm = ws_cms_pub_firm.id GROUP BY ws_cms_pub_firm.ID';
       $resource = mysql_query($sql);

$opts = array
(
'before_match' => '',
'after_match' => '
',
'chunk_separator' => ' ... ',
'limit' => 120,
'around' => 3,
);

while ($result = mysql_fetch_assoc($resource))
{

$stroka = $cl->BuildExcerpts(Array($result['opis'], $result['propisln']), "tovar", $str, $opts);

echo $stroka[0];

}

где

Array($result['opis'], $result['propisln']) - массив индексируемых текстов
tovar - индекс
$str - исходная строка для поиска
$opts - опции.

Только теперь проблема, как результат выводить, содержащийся в массиве $stroka.
К примеру $stroka[0] даст один из текстов, который не обзязательно содеражит поисковый запрос, т.к. он содержится например в $stroka[8].

В выданном сфинксом массиве, там где matches, fields... есть массив:
'words' =>
array
'слово1' =>
array
'docs' => int 7
'hits' => int 8
'слово2' =>
array
'docs' => int 10
'hits' => int 16
.....
Вопрос: Как установить кол-во элементов, выдаваемых этим массивом, array['words'] который?
У меня 10. Нужно 20. Плиз подскажите.

Почитайте о setLimits/maxMatches

Посмотрите, пожалуйста мой вопрос про BuildExcerpts.

Т.е.

$stroka = $cl->BuildExcerpts (Array ($result['opis'], $result['propisln']), «tovar», $str, $opts);

является общим массивом полей $result['opis'], $result['propisln'] и как отобразить результат непонятно, т.к. у одной записи он может содержаться в переменной $stroka[0], в другой $stroka[1].

setLimits задаёт колл-во в массиве 'matches'. В 'matches' у меня куча значений, которые меня не интересуют. Нужен массив 'words'. Повторю вопрос.
Как установить колличество элементов в массиве 'words', а не в 'matches' ?

Димко, Dexel, извините, но я НЕ пользуюсь SphinxApi, я использую исключительно SphinxSE, поэтому максимум могу порекомендовать почитать оф. документацию.

Не подскажите, можно ли через SphinxQL получить не только айдищникик, а все данные которые указаны в sql_query, чтоб не надо было потом из базы уже нчиего доставть?

у меня всё время возвращает только id, weight и поле из sql_attr_uint
Например

SELECT * FROM product WHERE MATCH ('@name HANGSLOT');
+---------+--------+----------------+
| id      | weight | data_source_id |
+---------+--------+----------------+
| 1397621 |   1591 |              3 |
| 1397624 |   1591 |              3 |
| 1397625 |   1591 |              3 |
| 1397626 |   1591 |              3 |
| 1397627 |   1591 |              3 |
| 1397628 |   1591 |              3 |
| 1397631 |   1591 |              3 |
| 1397632 |   1591 |              3 |
| 1397633 |   1591 |              3 |
| 1397634 |   1591 |              3 |
| 1397635 |   1591 |              3 |
| 1397638 |   1591 |              3 |
| 1397639 |   1591 |              3 |
| 1397640 |   1591 |              3 |
| 1397938 |   1591 |              3 |
| 1397942 |   1591 |              3 |
| 1397948 |   1591 |              3 |
| 1397949 |   1591 |              3 |
| 1397950 |   1591 |              3 |
| 1398295 |   1591 |              3 |
+---------+--------+----------------+

rostislav, насколько я знаю нельзя, придется жойниться с данными

adw0rd, не пойму как его установить на w7 ? ваши команды с начала поста не работают в cmd строке... можете дать сылку на дистрибутив движка, который вы устанавливали,а то я вижу пути по папкам у нас отличаются

Какие команды? Опишите последовательность ваших действий.

можете дать сылку на дистрибутив движка, который вы устанавливали,а то я вижу пути по папкам у нас отличаются

http://sphinxsearch.com/downloads.html скачивал тут. что именно не помню

Вы конечно все классные и умные ребята !!!! но блин какого вы все "юзаете" да это же кошмар!!!!!!!!!!!!!!!!!!!!!! тошнит от этих словечек сленговых!!!! есть такое красивое слово в русском языке - "использую" , "пользуюсь" и т.д!!!!

Elvis, ну кого от чего тошнит... Меня например часто тошнит от огромного количества восклицательных знаков ;)

adw0rd, спасибо за пост. Пригодилась. Поиск получился вполне приличный.

Подскажитей пожалуйста как выполнить через через SphinxQL запрос с COUNT
Всё время получаю ошибку

mysql> SELECT COUNT() FROM product WHERE data_source_id=3;
ERROR 1064 (42000): syntax error, unexpected '
', expecting TOK_DISTINCT near '*'

если делать
SELECT COUNT(DISTINCT @id) FROM product WHERE data_source_id=3;
то возвращает не число а список записей

а так?

COUNT(1)

тоже на работает... :(

А вот так?

SELECT @count FROM product WHERE data_source_id=3;

У меня нет возможности проверить синтаксис к сожалению

так тоже не работает :(

rostislav --

ну если звездочка не нравиться попробуй просто select count(id) from ...... есть же наверно какой то идентификатор у тебя ?

Здравствуйте!
Скажите, пожалуйста, как ускорить работу сфинкса?
Есть база, состоящая из 10000 документов. Каждый документ представляет собой статью размером 100-150 кбайт текста.
Так вот, поиск по этой базе по запросу, состоящему из 5-8 слов, занимает примерно 1-1,5 секунды. Это очень долго. Можно ли как то ускорить поиск?

  1. Как именно вы его используете? SphinxAPI/SE/QL?
  2. С какими настройками производите поиск? Сортировки/Релевантность?
  3. Какие характеристики у машины на которой работает searchd?
  4. Можно от вас получить лог запросов и время выполнения?
  1. Использую Sphinx API. При использовании SphinxQL время поиска сокращается приблизительно до 0,5 секунды.
  2. Сортировка по релевантности.
  3. Intel Celeron 633 MHz. 384 МБайта памяти. Ось FreeBSD 7.2.
  4. Кусок лога:
    [Fri Apr 30 10:59:51.713 2010] 1.027 sec [any/0/rel 9604 (0,20)] [] Анализ эффективности использования основных производственных фондов
    [Fri Apr 30 11:00:13.457 2010] 0.190 sec [any/0/rel 8330 (0,20)] [
    ] Статистические ряды динамики
    [Fri Apr 30 11:00:45.072 2010] 0.495 sec [any/0/rel 9428 (0,20)] [] Экономико- статистический анализ размеров и уровня оплаты труда
    [Fri Apr 30 11:04:14.012 2010] 0.256 sec [any/0/rel 9459 (0,5)] [
    ] Виды ценных бумаг
    [Fri Apr 30 11:04:45.225 2010] 2.156 sec [any/0/rel 9717 (0,5)] [] Актуальные проблемы возмещения налога на добавленную стоимость при экспорте товаров за пределы РФ
    [Fri Apr 30 11:05:16.173 2010] 1.380 sec [any/0/rel 9719 (0,5)] [
    ] Зоогигиеническая, санитарно-экологическая оценка молочно-товарной фермы на 200 коров племзавода ФГУП Чистые пруды Кировской области
    [Fri Apr 30 11:12:47.474 2010] 0.779 sec [any/0/rel 9719 (0,5)] [] Зоогигиеническая, санитарно-экологическая оценка молочно-товарной фермы на 200 коров племзавода ФГУП Чистые пруды Кировской области
    [Fri Apr 30 11:15:03.590 2010] 0.698 sec [any/0/rel 9716 (0,5)] [
    ] Виды и особенности антропогенных воздействий на природу
    [Fri Apr 30 11:15:32.093 2010] 1.192 sec [any/0/rel 9707 (0,5)] [] Проектирование участка дефектации Авторемонтного предприятия и разработка технологического процесса по устранению дефектов штока КПП КАМАЗ
    [Fri Apr 30 11:21:51.051 2010] 0.905 sec [any/0/rel 9704 (0,5)] [
    ] Гарантии прав профсоюзных объединений при осуществлении ими своих функций
    [Fri Apr 30 11:38:59.821 2010] 1.399 sec [any/0/rel 9703 (0,5)] [] Правовой режим земель промышленности, энергетики, транспорта, связи,радиовещания, телевидения, земли для обеспечения космической деятельности,земли обороны, безопасности
    [Fri Apr 30 13:09:32.806 2010] 0.825 sec [any/0/rel 9689 (0,20)] [
    ] Словообразовательная активность наименований живых существ и их организмов в современном английском языке
    [Fri Apr 30 13:44:18.078 2010] 0.708 sec [any/0/rel 9682 (0,5)] [*] Восприятие внешней и внутренней среды рецепторами или рецепция. Классификация рецепторов, рецепции и анализаторов
  1. На всех MATCH_MODE так себя ведет?
  2. А если не сортировать вообще?

Еще посмотрите http://sphinxsearch.com/blog/
Мне бы ваш индекс, я бы дома потестил. Кстати, а какая у вас версия Sphinx?

  1. Я пробовал только на SPH_MATCH_ANY.
  2. Попробую отпишусь.

Индекс порядка 700 метров занимает. 10000 документов индексировал около 3 часов....

Еще хотел спросить, а может ли сфинкс держать весь свой индекс в оперативной памяти, и если да, то поможет ли это ускорить поиск?

Добрый день.
Столкнулся с такой проблемой:необходимо проиндексировать поле таблицы
varbinary(max). Внутри хрянятся html документы довольно большого размера(>8000 байт).
в конфиге: sql_query =\
Select id, doctype, CAST(doc AS varchar(max)) from Table2
Sphinx 0.9.9(r2117) MSSQL
Проблема в том, что в этом случаем индексация идет только по первым 1024 символам документа. Если использовать CAST(doc AS varchar(8000), то по 8000 символов.
Ссылка на форум, где подробнее описана эта проблема
Там написано, что "перекомпилировать сфинкс, изменив константу размера поля по умолчанию".
Что для этого необходимо сделать?)
Заранее спасибо)

А doc какого типа в таблице?
Попробуйте

CAST (doc AS CHAR)
, может поможет

adw0rd, CAST (doc AS CHAR) так не помогло...
doc - varbinary (max).

Может стоит сменить тип у doc на TEXT? Просто у меня например проблем не было с TEXT, гораздо большего размера чем 8кб

К сожалению, менять тип поля нельзя...
Есть готовая база на 20 Гб, в которой необходимо организовать поиск.

Я вообще правельно понимаю, что перед индексацией данных в формате varbinary необходимо преобразовать их, например, в varchar? Или можно как-то иначе?

Не получается с установкой под Линукс.

  1. Вообще сервис встал нормально без ошибок после make и make install
  2. Файлы расположены так на сервере
    /usr/local/bin - тут все службы indexer, search, searchd
    /usr/local/etc/test - файлы индексации, которые генерирует Sphinx

Проблемы:
1. Команда "indexer --config /usr/local/bin/sphinx.conf --all" Срабатывает, выдает статистику (без каких либо ошибок), но файты в папке /usr/local/etc/test не появляются.
2. Команды search и searchd не срабатывают в ответ Command not found

До этого поставил у себя сборку Windows локально. Так все отлично работает. А с этим Линуксом теперь даже и не знаю. Подскажите, пожалуйста.

Хм... Переустановил с начала и все запахало. Чудеса.

Может прав не было на запись в каталог?
Ну а команды не доступны навеное в силу того, что не перехешировались имена... надо было наверное полный путь до них. Но если из вообще не было, то что-то явно не так вставало :) так что переустановка - самое то

Не могу произвести индексацию:
indexer --config /home/sphinx/sphinx.conf --all
FATAL: config file '/home/sphinx/sphinx.conf' does not exist or is not readable

Пробовал решить проблему так:
sudo chmod 0777 /home/sphinx/
chmod: невозможно получить доступ к «/home/sphinx/»: Нет такого файла или каталога
и так:
sudo chmod 0755 /home/sphinx/sphinx.conf
chmod: невозможно получить доступ к «/home/sphinx/sphinx.conf»: Нет такого файла или каталога
Пути правильные, название папки и файла тоже.Подскажите в чём может быть проблема?

Sphinx устанавливал через Synaptic.

уже справился с проблемами, спасибо)

В конфиге прописал так:
sql_query = SELECT billb_id, billb_title, billb_min_desc, billb_full_desc FROM gookit_billboard

делаю
indexer --config /home/sphinx/sphinx.conf --all

# indexer --config /home/sphinx/sphinx.conf --all Sphinx 1.10-beta (r2420) Copyright (c) 2001-2010, Andrew Aksyonoff Copyright (c) 2008-2010, Sphinx Technologies Inc (http://sphinxsearch.com) using config file '/home/sphinx/sphinx.conf'... indexing index 'maxim_wp'... collected 12 docs, 0.0 MB sorted 0.0 Mhits, 100.0% done total 12 docs, 339 bytes total 0.030 sec, 11115 bytes/sec, 393.48 docs/sec total 2 reads, 0.000 sec, 6.8 kb/call avg, 0.0 msec/call avg total 6 writes, 0.000 sec, 5.0 kb/call avg, 0.0 msec/call avg

потом делаю, к примеру:
search –-config /home/sphinx/sphinx.conf red

выдает ошибку

using config file '/usr/local/etc/sphinx.conf'... index 'test1': search error: failed to open /var/data/test1.sph: No such file or directory.

его там и нет. Что сделать? И что я натварил не так? Спасибо.

обратите внимание на знаки тире (--config), в пример где у вас ошибка там какой-то он кривой ;)

вот еще когда сервер запускаю пишит

# searchd Sphinx 1.10-beta (r2420) Copyright (c) 2001-2010, Andrew Aksyonoff Copyright (c) 2008-2010, Sphinx Technologies Inc (http://sphinxsearch.com) using config file '/usr/local/etc/sphinx.conf'... FATAL: failed to lock pid file '/var/log/searchd.pid': Resource temporarily unavailable (searchd already running?)

типа заблокирован файл, делаю на него chmod 777 все равно такая барада.

А он вообще существует? Что пид-файл делает в каталоге логов?
Создайте каталог /var/run/sphinxsearch/ для /var/run/sphinxsearch/searchd.pid
Назначьте права нужные, например:
chown -R sphinx:sphinx /var/run/sphinxsearch
и проверьте что туда можно писать
chmod -R +w /var/run/sphinxsearch

А по простому надо вам сделать chmod -R 777 /var/log

Спасибо, отлегло.

adw0rd, мне нужно реализовать поиск по множетсву таблицам
для этого Я создаю много source

source выв source sdf

а что делать с этим параметром?

# Использовать соответствующий source-блок настроек при индексации source = adw0rd_wp

и как все это отображать в index.php там где у меня api?

желательно примерчик покажи, спасибо.

Для каждого index делаете source, а при поиске перечисляете по каким индексам вы хотите искать, например для sphinxse будет выглядить так:


index=выв,sdf;

А для API читайте тут http://sphinxsearch.com/docs/current.html#api-reference, я им не пользуюсь.

Добавил idnex и source вот так

source articles_wp { # Запрос выборки данных для индексации sql_query = SELECT articles_id, articles_date, articles_user_id, articles_title, articles_description, articles_full, articles_foto FROM gookit_articles; # Запрос доп. информации для вывода результата (используется утилитой "search") sql_query_info = SELECT * FROM gookit_articles WHERE articles_id = $id # Время простоя (sleep) перед посылкой запросов серверу (предназначен для разгрузки сервера БД) # Если установите "= 1000", то засыпание будет длится 1 секунду sql_ranged_throttle = 0 }
и index
index articles_wp { # Использовать соответствующий source-блок настроек при индексации source = articles_wp # Путь до файлов индекса path = /home/sphinx/data/articles_wp # Способ хранения индекса (none, inline, extern) # Подробнее http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-docinfo docinfo = extern # Memory lock (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-mlock) mlock = 0 # Использование английского и русского стемминга morphology = stem_enru # Минимальная длина индексируемого слова min_word_len = 2 # Установка используемой кодировки charset_type = utf-8 # Таблица символов (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-charset-table) 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 # Использовать оператор усечения "*" (http://www.sphinxsearch.com/docs/manual-0.9.8.html#conf-enable-star) enable_star = 1 }

потом делаю так

indexer --config /home/sphinx/sphinx.conf --all

выдает ошибку,

using config file '/home/sphinx/sphinx.conf'... indexing index 'adw0rd_wp'... FATAL: failed to lock /home/sphinx/data/adw0rd_wp.spl: Resource temporarily unavailable, will not index. Try --rotate option.

Потом делаю chmod дает туже ошибку
потом делаю

indexer --config /home/sphinx/sphinx.conf --rotate

и иду делать поиск
В первой таблице поиск прошел успешно, во второй

дало ошибку

using config file '/home/sphinx/sphinx.conf'... index 'adw0rd_wp': query 'статьи ': returned 0 matches of 0 total in 0.000 sec words: 1. 'статьи': 0 documents, 0 hits 2. 'стат': 0 documents, 0 hits index 'articles_wp': search error: /home/sphinx/data/articles_wp.sph is invalid header file (too old index version?).

Ну вроде и так все понятно

invalid header file (too old index version?).

А вообще файл "/home/sphinx/data/articles_wp.sph" существует?

Вам надо запускать сначала полную индексацию (all), а не rotate, так как у вас еще нет файлов индекса "articles_wp".
А чтобы не возникало ошибки

FATAL: failed to lock /home/sphinx/data/adw0rd_wp.spl: Resource temporarily unavailable, will not index. Try --rotate option.
надо останавливать searchd.

эдвo, с indexer все прошло на ура спасибо. Даже не подумал право откл серв %)
А вот поиск выдет теперь каку

# search --config /home/sphinx/sphinx.conf tits Sphinx 1.10-beta (r2420) Copyright (c) 2001-2010, Andrew Aksyonoff Copyright (c) 2008-2010, Sphinx Technologies Inc (http://sphinxsearch.com) using config file '/home/sphinx/sphinx.conf'... index 'adw0rd_wp': query 'tits ': returned 0 matches of 0 total in 0.000 sec words: 1. 'tits': 0 documents, 0 hits index 'articles_wp': search error: failed to open /home/sphinx/data/articles_wp.sph: No such file or directory.
создаю файйл ошибка новая
# search --config /home/sphinx/sphinx.conf tits Sphinx 1.10-beta (r2420) Copyright (c) 2001-2010, Andrew Aksyonoff Copyright (c) 2008-2010, Sphinx Technologies Inc (http://sphinxsearch.com) using config file '/home/sphinx/sphinx.conf'... index 'adw0rd_wp': query 'tits ': returned 0 matches of 0 total in 0.000 sec words: 1. 'tits': 0 documents, 0 hits index 'articles_wp': search error: /home/sphinx/data/articles_wp.sph is invalid header file (too old index version?).

/home/sphinx/data/articles_wp.sph

да есть!

с Этим со все разобрался! Из консоли работает отлично уже по 5 таблицам.
Проблема была в том что Таблицу изменили и при indexer он искал левое поле. (Об изменении в структуре БД я не знал)

Проблема остается в том как в скрипте для работы с проиндексируемыми данными поисковика index.php описать запрос для работы с множеством таблиц.
Если были такие задачи просьба поделится советом.
Уфф! почти сделал, даже не верится. Спасибо, кстати за помочь!!!

Проблема остается в том как в скрипте для работы с проиндексируемыми данными поисковика index.php описать запрос для работы с множеством таблиц.
С множеством индексов? Или что?
Если ты про индексы, то я давал уже тебе ссылку в ман, видимо ты не хочешь читать...


$cl->Query ( "test query", "main delta" );
$cl->Query ( "test query", "main;delta" );
$cl->Query ( "test query", "main, delta" );

http://sphinxsearch.com/docs/current.html#api-func-query

Замечательный пост. Благодаря Вам установил и разобрался с sphinx, пока есть проблемы, но результаты вполне устраивают, поиск по индексам в бд срабатывает и довольно быстро. Была проблема при передачи ассоциативного массива в другой кодировке, отличной от юникода, но при переключении браузера в юникод все сработало. Спасибо.

Добрый день, вопрос по ранжированию результатов поиска:
есть таблица с продуктами, у каждого продукта есть характеристика "популярность". можно ли в Сфинкс сделать ранжирование, чтоб учитывалась и популярность, и релевантность названия+описания продукта, с разными весами? Например, популярность определяет 60%, а релевантность 40%.
Сейчас есть другой поисковый движок, там это сделать проблематично, изучаю возможность перевода на Сфинкс, и это ключевой вопрос - можно ли так настроить ранжирование
Заранее благодарен!

Я не работаю с API, а в SphinxSE это есть http://sphinxsearch.com/docs/manual-0.9.9.html#sphinxse-using

Спасибо за статью. Очень помогла.

Подскажите пожалуйста, как в Вашем примере реализовать вывод с подсветкой результатов?
BuildExcerpts(); - Можно пример.

Заранее благодарен.

В комментариях к статье описывается использование BuildExcerpts

Вот у меня глюк какой странный.
OS linux
База данных mysql в utf-8
Сами страницы сайта тоже в utf-8
Стоит сфинкс 0.9.9-release
Всё работало.
Потом "внезапно" перестало. Причём так:
С латинницей всё работает
Задаю из командной строки ./search -c /var/www/html/site/shpinx/etc/sphinx.conf лампа - работает
А делаю вызов через API @fsockopen ( $this->_host, $this->_port ) делает вид что работает, но овзвращает пустой результат :(

Ещё странность:
Общий объём данных, выдёргиваемых из таблицы для индексации 135 метров.
Раньше общий объём создаваемых индексных файлов был 170 метров, а после того, как "всё сошло с ума" - 117

Я делаю вывод, что что-то не так у индексатора, но не могу понять что!??!

А переиндексацию полную пробовали запускать?

Неоднократно.
Уже не знаю сколько попыток сделал.
В конце-концов пришёл к выводу, что у меня что-то не так с пониманием кодировки.
Сервер весь в utf-8 , mysql - utf-8
Все настройки ставлю для сфинкса utf-8

На самом деле, я перепробовал уже все мыслимые комбинации :(
sql_query_pre = SET CHARACTER_SET_RESULTS=utf8
charset_type = sbcs
Пробовал добавлять/удалять charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F

Получаются копмлекты индексных файлов разнообразной длины, латиницу ищет нормально, а кириллицу не желает искать ни в какую :(

Здравствуйте! Не мог бы мне кто помочь с настройкой службы searchd. У меня поиск через search работает, с ним всё в порядке.
Устанавливаю searchd таким образом:
searchd --install --config c:\sphinx\sphinx.conf
В службах появляется searchd. Однако, когда я её пытаюсь запустить через консоль, у меня консоль зависает, и в ней набрать ничего нельзя. Вот, что происходит:


C:\sphinx\bin>searchd --config c:\sphinx\sphinx.conf
Sphinx 1.10-beta (r2420)
Copyright (c) 2001-2010, Andrew Aksyonoff
Copyright (c) 2008-2010, Sphinx Technologies Inc (http://sphinxsearch.com)

using config file 'c:\sphinx\sphinx.conf'...
listening on all interfaces, port=9312
precaching index 'catalog'
precached 1 indexes in 0.027 sec

в папке catalog должны находиться индексы..

Заранее благодарен!

z_alex,

Однако, когда я её пытаюсь запустить через консоль, у меня консоль зависает, и в ней набрать ничего нельзя.

так и должно быть. служба нормально запустилась и прослушивает порт 9312.
посылай запросы на него через АПИ сфинкса или через МУСКУЛ запросы

// Получаем массив ID постов блога $ids = array_keys($result['matches']);

Таким образом мы не получим ID постов блога, ведь они в $result['matches'][]['id']
По крайней мере, у меня они там.

SetLimits(1,10);

Так не правильно, мы пропустим первую и самую релевантную запись. И программисты всегда считают с нуля и в метре 1024 сантиметра.
Поэтому нужно так:

SetLimits(0,10);

Прошу прощения, как оказалось первое утверждение верно если сделать SetArrayResult(true);

День добрый.

Большое спасибо за статью. Я попробовал - все работает и очень шустренько. Только одну проблему не могу понять как решить. Дело в том, что есть две таблички. В одной (persons) лежат ФИО разных личностей, а в другой (person_cv) на каждого из них кратенькая статья (поле типа text размер ср. статьи - неск. килобайт максимум). Индекс построен на запросе, который соединяет эти две таблички (равновесное соединение в отношении один к одному). И вот хочется чтобы, если я задаю поиск по фамилии "Иванов", то находились не только собственно записи, у которых в табличке persons есть эта фамилия, но и ее упоминания в статьях других записей. А вот этого почему то не происходит. Если я задаю критерием поиска "Иванова", то ищет вхождения в табл. person_cv с разными окончаниями (Иванова, Иванову и пр.), но сами записи в табл. persons из итогов поиска пропадают. Вызов из php стандартный:

$string = 'Иванов';
$sphinx = new SphinxClient();
$sphinx->SetServer('localhost', 3312);
$sphinx->SetMatchMode(SPH_MATCH_ANY);
$sphinx->SetSortMode(SPH_SORT_RELEVANCE);
$sphinx->SetFieldWeights(array ('L_NAME' => 20, 'CV' => 15));
$result = $sphinx->Query($string, '*');

Заранее спасибо за просвещение.

Всех благ...

А при поиске "Иванов" и "Иванова" какое кол-во результатов для каждого?

Отличная статья, поднял sphinx на win7x64 за пол часа совершенно без напряга, спасибо adw0rd!

какая-то фигня

SetServer возвращает false, поиск не ведется,
хоти из командной строки все работает. ось freebsd.

sockstat -4:
root searchd 31885 5 tcp4 127.0.0.1:3312 :

скрипт:
require_once('sphinxapi.php');
$sphinx = new SphinxClient();

if(!$sphinx->SetServer('127.0.0.1', 3312)) {
echo 'error connection'; exit;
}

...

все разобрался. подумайте только, проблема блин была в том что у меня было max_matches = 500 а можно я так понял max_matches = 1000 минимум. из-за такой фигни пол дня парился. и в логах ничего не писалось :(

Доброго времени суток. Спасибо за статью - помогла.

Вопрос: Возможно ли средствами sphinx реализовать "возможно Вы искали ..." (например человек искал "яблоки", а ввел "яблки"), или это нужно пхп-обертку писать. Если пхп, то не подскажите алгоритм.
Заранее спасибо

Да, средствами SphinxSearch это возможно сделать, для этого есть http://code.google.com/p/sphinxsearch/source/browse/trunk/misc/suggest/
Насколько я помню именно это решение предлагали на одной из конференций разработчики сфинкса, вообще посмотрите

Вот ещё релейтед пост на хабре http://habrahabr.ru/post/61807/

у меня пару вопросов. как правильно обновлять индекс, чтоб как можно меньше ресурсов тратилось?

/usr/local/bin/indexer --config /home/sphinx/sphinx.conf --rotate
у меня выдает

ERROR: nothing to do.

а /usr/local/bin/indexer --config /home/sphinx/sphinx.conf --all --rotate

я так понимаю полностью пересобирает индекс?! это не дело. и еще, как посоветуете запускать сфинкс, мне нужно чтобы не из под рута, но чтобы mlock работал

и еще у меня параллельно такой вопрос, как быть с ё ? как ее включить в индекс?

Господа, а что, тема Сфинкса замерла?

Да наверное все и всех устраивает, нет?

можете подробно объяснить как с помощью функции SetLimits сделать постраничную навигацию в
результатах поиска

типа << <1 | 2 | 3 | 4> >>

Делаете как и везде:

/?page=1
/?page=2
/?page=3
/?page=4

Дальше обрабатываете так:

paginated_by = 20  # Количество объектов на странице
offset = (page * paginated_by) - paginated_by
SetLimits(offset, paginated_by)

Вообщем как и везде...

А смысл к БД подключаться? В твоем примере sphinxapi.php ты поиск опять же по MySQL даешь. А сфинкс тебе зачем тогда?

Поиск через Sphinx, а выборка доп. данных через MySQL, читайте внимательнее

ссылочка про docinfo = extern не рабочая((

Ну за 5 лет все поменялось)

Найдите информацию на оф. сайте http://sphinxsearch.com/docs/

При поиске ошибка:
Deprecated: DEPRECATED: Do not call this method or, even better, use SphinxQL instead of an API in C:\sphinx\api\sphinxapi.php on line 789.
Это значит не нужно использовать АПИ?

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

Markdown