SphinxSearch и MongoDB на примере HaipIT News

Приветствую, Земляне!

В данной статье я расскажу, как настроить поиск Sphinx таким образом, чтобы он мог выполнять индексацию базы данных Mongo (про работу с индексом через PHP код в другой раз).

Наверно многие из вас в курсе, что последние пару неделю я работаю над очередным своим проектом под названием HaipIT News, суть данного проекта - агрегация новостей из некоторых любимых мною источников. Проект пока ещё находится в стадии разработки. но уже много чего сделано, например API которое работает напрямую с базой данных MongoDB и ряд скриптов для импорта новостей из источников и частично завершённый Web-интерфейс.

Изначально для поиска я планировал реализовать связку MongoDB и ElasticSearch, это у меня получилось при помощи специального плагина. Наигравшись с ElasticSearch пришёл к выводу, что это не самая подходящая для меня система. Да, у ElasticSearch очень круто настраиваются словари, очень легко реализовать интеграцию в код, из коробки поддерживаются кластеры Mongo, но со временем Elastic стала очень странно себя вести, ps aux и service status показывали что всё нормально, но любая попытка сделать запрос возвращала null. После нескольких попыток заставить Elastic работать (restart в crontab помогал некоторое время), я разочаровался в этой идее и принялся искать более надёжное решение. И им, как не сложно догадаться, оказался Sphinx, у меня уже был большой опыт работы с данных сервером раньше, но я никогда не настраивал индексацию MongoDB.

Как показала практика, сделать это очень просто:

Sphinx (установить и настроить)

Для счастливых обладателей Debian-like дистрибутивов всё должно быть очень просто:

sudo apt-get install sphinxsearch

Дальше создадим конфиг, который будет запускать генератор XML:

sudo mcedit /etc/sphinxsearch/sphinx.conf

Запишем в него следующее

Жирным шрифтом я выделил пару моментов:

  • xmlpipe2 - тип данного источника, для всех современных версий Sphinx стоит выбирать именно его, так как первая версия просто не работает
  • /home/king/sphinx-index.php - название и путь к скрипту генератору, это может быть любая программа или скрипт, главное чтобы данные которые он возвращает в процессе работы были в формате XML, php показан только как пример
  • mongo - название нашего индекса, оно понадобится нам в дальнейшем

Скрипт, для генерации XML

Создадим файл /home/king/sphinx-index.php:

mcedit /home/king/sphinx-index.php

Со следующим содержимым:

Выполнение данного скрипта должно отображать нам что-то вроде:

Если Вы видите что-то подобное, значит всё хорошо и данные из монги выгружаются как надо, на самом деле это может быть какая угодно база данных (а может вы хотите индексировать файловую систему), важно только чтобы данные были в формате XML.

Выполним индексацию

Тут всё просто, для того чтобы выполнить индексацию нужно выполнить следующую команду:

sudo indexer mongo

Где mongo это название индекса, который мы прописали в конфиге /etc/sphinxsearch/sphinx.conf. В дальнейшем мы будем только обновлять индекс, следующей командой:

sudo indexer mongo --rotate

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

Завершение

Как видно из статьи, реализовать индексацию данных, находящихся в Mongo очень просто, работать с индексом так же просто как настраивать его. А высокая скорость работы будет радовать Вас ещё очень долго, если время отклика важно для Вас. Например моя база (на момент выхода данной заметки), содержит в себе около 10000 документов, размер индекса составляет около 10Мбайт, а время генерации индекса почти одна секунда, неплохой результат как по мне.

А на этом всё, напомню что в Discord есть сообщество программистов, в котором я принимаю активное участие, поэтому если у Вас возникнут вопросы, обращайтесь, не стесняйтесь, ну или в Twitter @EvilFreelancer например.

2 thoughts on “SphinxSearch и MongoDB на примере HaipIT News

  1. Вот Вы написали: "а может вы хотите индексировать файловую систему".
    Не подскажете как изменить XML, чтобы путь к файлу с именем файла (полное имя в общем) заносился в индекс и выдавался оттуда по запросу?

    Я занес его в атрибут:

    testing
    Проиндексировал, но получить не могу:
    $result = $sphinx->query('testing ', '*');

    Array ( [error] => [warning] => [status] => 0 [fields] => Array ( [0] => content ) [attrs] => Array ( ) [matches] => Array ( [3] => Array ( [weight] => 1 [attrs] => Array ( ) ) ) [total] => 2 [total_found] => 2 [time] => 0.000 [words] => Array ( [test3] => Array ( [docs] => 2 [hits] => 2 ) ) )

    Какой командой вытащить атрибут? Или нужно не в атрибут, а еще в один элемент Путь засунуть?

    1. Всё зависит от того какие данные Вы передаёте на вход Sphinx, есть лишь одно условие - они должны быть в формате XML, я бы наверно сделал xml поле в котором была бы необходимая для индекса информация (имя файла например). На самом деле упоминание файловой системы это отсылка к одному проекту в котором я участвовал, он как раз был про индексирование ФС, но не через Sphinx, а через C++ вызовы.
      PS. Прошу прощения за долгий ответ, только что разобрал весь спам в коментариях и обнаружил Ваше сообщение.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *