Наши партнеры

UnixForum






Книги по Linux (с отзывами читателей)

Библиотека сайта rus-linux.net

На главную -> MyLDP -> Тематический каталог -> СУБД для Linux

Поиск в базах данных с помощью Sphinx

Оригинал: Searching database content with Sphinx
Автор: Federico Kereki
Дата: 24 августа 2007
Перевод: Александр Тарасов aka oioki
Дата перевода: 1 сентября 2007
Перепечатка статьи разрешается только при условии указания ссылки на оригинал и первоисточник перевода.

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

Sphinx (сокращение от "SQL Phrase Index") может индексировать большие объемы текста - до 232 (немногим больше 4 миллиардов) записей базы данных, содержащих несколько полей. Имеется поддержка простых и составных поисковых выражений, к примеру, можно произвести поиск документа, содержащего слова ТЕОРИЯ ОТНОСИТЕЛЬНОСТИ и одно из ЧАСТНАЯ или ОБЩАЯ, но не КВАНТОВАЯ.

Andrew Aksyonoff начал разработку Sphinx в 2001. Ему была нужна быстрая система с хорошим качеством поиска, в то же время обладающая средними требованиями к компьютеру, но он такой не нашел. Текущая версия Sphinx - 0.9.7, в разработке находится версия 0.9.8. Веб-сайт Sphinx обновляется не очень часто: новые версии выходят редко, но несут в себе значительные изменения и доработки.

Sphinx работает в контексте LAMP (Linux/Apache/MySQL/PHP). Многие системы управления содержанием (CMS) используют MySQL для данных и написаны на PHP, так что они годятся для работы со Sphinx. Можно также запустить Sphinx на BSD (FreeBSD, NetBSD), Solaris и даже Windows. Для программистов Sphinx предоставляет библиотеки для языков Ruby, Perl и Python, однако для Java библиотеки нет.

Программа является свободной и может распространяться и изменяться по условиям лицензии GPLv2 либо более поздней версии.

Индексирование

Sphinx может обрабатывать не только таблицы MySQL, но также таблицы PostgreSQL и текстовые файлы XML. Однако есть некоторые ограничения при работе с XML, эта технология намного менее гибкая, чем базы данных. Основная идея Sphinx - индексирование некоторых таблиц в вашей базе данных, после чего пользователь может производить поиск внутри этих таблиц на основе индекса.

Возможно индексирование текстовых полей в любой таблице. Все индексируемые таблицы должны содержать поле ID, чтобы Sphinx при необходимости смог получить полную запись. Sphinx может даже смешивать записи из различных таблиц, единственное требование - поле ID должно быть уникальным во всех таблицах. Возможно индексировать до 32 текстовых полей и несколько "атрибутов" (целочисленные или временные), которые используются не для индексирования, а для дальнейшей фильтрации: к примеру, вы можете произвести поиск записей, сделанных до определеной даты.

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

  • использовать ли "stemming" (поиск однокоренных слов): это означает, что если вы ищете слово "swim", будут также отображены слова "swimming" и "swimmer". Есть поддержка русского и английского (как написано на веб-сайте, в версии 0.9.8 планируется поддержка французского, испанского, португальского, итальянского, немецкого, голландского, шведского, норвежского, датского, финского, венгерского и турецкого языков). Либо вы можете использовать Soundex (алгоритм поиска схожих по звучанию слов, работает лишь для английского языка).
  • применять ли "stop words": обычно короткие слова, которые встречаются настолько часто, что их включение в индекс нецелесообразно. Типичные примеры - английские слова "the", "a", "of".
  • минимальная длина слова: слова короче этой величины не будут включены в индекс. Типичное значение - 4.
  • кодировка данных: возможно указание Windows-кодировок SBSC (однобайтовые кодировки) либо Linux/Unix кодировки UTF-8 (в которой символ может представляться более чем одним байтом).
  • использовать ли folding-правила: учитывать ли регистр символов, и воспринимать ли символы подобные "á" и "ë" как неакцентированные эквиваленты. Немецкие пользователи должны обратить внимание, что в настоящее время нет поддержки перевода "ß" в "ss" и "ö" в "oe"; классические англичане наверняка будут требовать перевод лигатур "æ" и "œ" в соответствующие пары букв.
  • разделители слов: все символы, не перечисленные в только что упомянутом наборе, рассматриваются как разделители слов, и не будут индексироваться.
Для баз данных, размер которых превышает 100 Гб, возможно использование распределенных индексов и поиска. То есть, вы можете разделить данные на несколько машин и производить поиск параллельно, чтобы уменьшить время отклика и нагрузку сервера. Поисковые запросы будут распределены по машинам, но результаты будут сгруппированы перед отправкой пользователю. Этот подход также предлагается для мультипроцессорных систем, хотя детали этого в документации не отражены.

Если вам нужно обновление в реальном времени, вы можете использовать один искусственный прием, который не затрагивает старые записи. Он основан на концепции "дельта-обновления" ("дельта" означает различие между старой таблицей и новой). Допустим, у вас есть 2 источника данных и 2 индекса: один для основной части (предполагается, что она не будет часто переиндексироваться) и один для ежедневных обновлений (меньше, поэтому может переиндексироваться чаще и быстрее). Периодически (когда дельта-часть станет ощутимой) вы переиндексируете все данные, и начинаете с новой пустой дельтой. Это не лучшее решение; автор программы работает над быстрыми обновлениями в реальном времени для версии 1.0.

Если вы имеете дело с записями, которые могут обновляться (а не только добавляться), тогда наверное вам нужно рассмотреть вариант перестройки индекса с нуля. С другой стороны, так как индексирование производится быстро, это может не быть такой большой проблемой.

Поиск

Поиск в индексе производится двумя путями: вы либо используете предоставленную автономную программу, либо программируете свой собственный скрипт поиска, основанный на стандартном API, который использует возможности демона searchd, работающего в фоновом режиме. Вы можете настроить MySQL для использования подключаемого движка (SphinxSE), позволяющего производить поиск изнутри SQL безо всяких драйверов или API. С другой стороны, этот движок требует компиляции MySQL из исходников, и может не подходить вам, так что, пожалуй, он полезен лишь в образовательных целях.

В любом случае, если вы привыкли к поиску в интернете (к примеру, на Google) вы будете комфортно чувствовать себя в окружении Sphinx со стандартными операторами запросов:

  • Запросы И: ELLINGTON & ARMSTRONG выдает документы, содержащие как ELLINGTON, так и ARMSTRONG. Кстати, использование амперсанда необязательно: ELLINGTON ARMSTRONG выдаст то же самое.
  • Запросы ИЛИ: ELLINGTON | ARMSTRONG выдает документы, содержащие либо ELLINGTON, либо ARMSTRONG, либо и то и другое.
  • Запросы НЕ: ELLINGTON -ARMSTRONG выдаст результаты, содержащие ELLINGTON, но не содержащие ARMSTRONG. Запрос, подобный -ARMSTRONG несет мало смысла; в списке результатов окажутся почти все документы.
  • Поиск по полю: @title SOLITUDE @author ELLINGTON будет искать SOLITUDE в поле "title" и ELLINGTON в поле "author". Очевидно, пользователям нужно знать, какие поля доступны, так что позаботьтесь об этом.
  • Поиск по фразе: если вы сделаете запрос "DUKE ELLINGTON", будут выданы те документы, в которых слова DUKE и ELLINGTON идут именно в таком порядке.
  • Приближенный поиск: вариант последнего случая, к примеру "DUKE ELLINGTON"~10 означает, что указанные слова должны быть разнесены не более чем на 10 слов друг от друга.
Другие возможности:
  • Поисковой API позволяет вам назначить вес каждого поля так, чтобы совпадение в каком-то поле было более "весомым", чем совпадение в других полях.
  • Поисковой API позволяет сортировать результаты по релевантности, дате, атрибутам или по введенному вами SQL-выражению.
  • Если вас интересует лишь статистика (к примеру, вы хотите знать количество сообщений на форуме за месяц, либо сколько написал какой-то человек), вы можете сгруппировать результаты вместо получения каждого документа, и каждой группе будет соответствовать одно наилучшее совпадение (то есть, одна запись - наиболее подходящая из всех записей в группе) и искомое число.
Заметьте, что нельзя делать запросы по шаблону наподобие "UNIT* ST?T?S". Это обычное ограничение систем полнотекстового поиска: выполнение таких запросов чрезвычайно неэффективно, неважно, какой индекс вы уже построили.

Заключение

Два преимущества этого продукта - скорость и подтвержденная способность работы с действительно большими наборами данных. Я не проводил свои исследования, но на сайте программы утверждается скорость до 10 Мб/с на современных процессорах, и скорость выполнения запроса менее 1/10 секунды в базе данных размером 2-4 Гб. Последние цифры особенно впечатляют, на сайте есть ссылки на другие сайты, которые используют систему Sphinx (включая сайт MySQL AB), один из таких сайтов содержит базу данных в 1,5 Тб, пополняемую 1 миллиардом посетителей форума.

К недостаткам можно отнести документацию Sphinx - она не так хороша, как производительность системы. К примеру, чтобы заставить интерфейс PHP заработать, мне пришлось изучить пример кода и дедуктивным методом вывести, какие вызовы использовать и какие параметры передавать. Это также справедливо и для API других языков. Также мне не удалось найти спецификацию двоичного протокола. Более сложному конфигурированию (распределенная установка и индексирование) должны сопутствовать полные примеры и диаграммы, а их нет. Примеры ориентированы на MySQL; вам придется рассчитывать на себя, если у вас PostgreSQL. Способности по обработке XML слабы и слишком строги; функции обработки более обычных XML-схем было бы кстати. Наконец, если вам нужны обновления в реальном времени, если "дельта"-решение вам не подходит, подождите до версии 1.0.

Пока разработчики занимаются новой версией, мы отметим, что достоинства Sphinx перевешивают недостатки. Хотя версия еще не 1.0, тем не менее Sphinx является стабильным и мощным поисковым средством, и я планирую его использовать в дальнейшем.


Обсуждение статьи на форуме LOR.