Обзор решений для полнотекстового поиска в веб-проектах: Sphinx, Apache Lucene, Xapian
Введение
Любой разработчик, реализующий сегодня какой-либо проект, сталкивается с потребностью реализовать поиск в своём веб-приложении. Конечно, для каких-то проектов вполне подойдёт и простое решение, к примеру, от Google. Но чем более сложное приложение, и чем сложнее структура контента, если требуются особые виды поиска и обработки результата — тем большая потребность в собственной реализации. Но что же выбрать, какие сейчас на рынке есть поисковые проекты, которые готовы для использования в реальных проектах, не исследовательских или научных, а реальных приложениях? Далее мы кратко рассмотрим различные варианты поисковых решений, пригодных для встраивания или развёртывания на собственном сервере.Общая архитектура и термины
Под поисковым сервером (или просто «поисковик») мы понимаем библиотеку или компонент, вообще, программное решение, которое самостоятельно ведёт свою базу данных (на самом деле это может быть и СУБД, и просто файлы и распределения платформа хранения) документов, в которых и происходит поиск. Поисковик также предоставляет сторонним приложениям возможность добавлять, удалять и обновлять документы в этой базе. Этот процесс называется индексированием, и может быть реализовано отдельным компонентом или сервером (индексатором). Другой компонент, поисковый механизм, принимает запрос на поиск и обрабатывая созданную базу, производит выборку данных, которые соответствуют запросу. Кроме этого, он может вычислять дополнительные параметры для результатов поиска (ранжировать документы, вычислять степень соответствия поисковому запросу и т. п.). Это самые важные системы поисковика, и они могут быть как монолитно реализованы в одной библиотеке, так и быть самостоятельными серверами, доступ к которым реализуется через различные прикладные протоколы и API.Отдельно я бы выделил наличие модуля реализации веб-поиска. То есть, в поисковом сервере может быть реализована встроенная возможность получать документы с веб-сайтов по протоколу НТТР и заносить их в индекс. Этот модуль называется обычно «паук» или «crawler», и таким образом, поисковый сервер уже может быть похож на «настоящий» и привычный всем поиск вроде Google или Yandex. Так можно реализовать собственный поисковик по нужным вам сайтам, например, посвящённым одной теме — достаточно просто создать список адресов и настроить их периодических обход. Однако это уже задача гораздо более сложная и серьёзная, как технически, так и организационно, поэтому мы не останавливаемся на деталях её реализации. Среди проектов, которые мы рассмотрим, присутствует один сервер, именно реализующий веб-поисковик, то есть содержит все необходимое для создания «убийцы Яндекса». Интересно?
Какие параметры важны?
При выборе поискового механизма следует учитывать следующие параметры:- скорость индексирования — то есть, как быстро поисковый сервер «перемалывает» документы и заносит их в свой индекс, делая доступным поиск по ним. Обычно измеряется в Мб чистого текста в секунду (обычно в тестах это 1U сервер, вроде 2 ГГц CPU и 1 Гб RAM + SATA диск или RAID).
- скорость переиндексации — в процессе работы документы изменяются или добавляются новые, поэтому приходится заново индексировать информацию. Если сервер поддерживает инкрементное индексирование, то мы обрабатываем только новые документы, а обновление всего индекса оставляем на потом или даже можем вообще не делать.
- поддерживаемые API — если вы используете поисковик в связке с веб-приложением, обратите внимание на наличие встроенного API к вашему языку или платформе.
- поддерживаемые протоколы — обычно поддерживаются
XML-RPC или JSON-RPC, SOAP или доступ через http/socket. - размер базы и скорость поиска — эти параметры очень взаимосвязаны и если вы реализуете что-то уникальное и предусматриваете, что у вас могут быть миллион и больше документов в базе, то посмотрите на известные реализации выбранной платформы. Хотя никто не заявляет явно про ограничения на количество документов в базах, и на небольших коллекциях (например, несколько десятков тысяч документов) все поисковики будут примерно одинаковые, но если речь идёт о миллионах документов — это может стать проблемой.
- поддерживаемые типы документов — конечно, любой сервер поддерживает обычный текст (хотя следует смотреть на возможность работы с многоязычными документами и кодировкой UTF-8), но если вам необходимо индексировать разные типы файлов, например, HTML, XML, DOC или PDF, то стоит посмотреть на те решения, где есть встроенный компонент для этого. Конечно, все это можно сделать прямо в вашем приложении, но лучше поискать готовые решения. Сюда же относится и поддержка индексирования и поиска информации, которая хранится в СУБД — не секрет, что такое хранение самое распространённое для веб-приложений, и лучше, чтобы поисковый сервер работал напрямую с базой данных.
- работа с разными языками и стемминг — для корректного поиска с использованием разных языков необходима родная поддержка не только кодировок, но и работа с особенностями языка. Все поддерживают английский язык, который для поиска и обработки достаточно простой. Модуль стемминга позволяет склонять и разбирать слова в поисковом запросе для более корректного поиска. Если для вас критичен поиск на русском языке, обратите внимание на присутствие этого модуля и его особенности.
- поддержка дополнительных типов полей в документах — кроме самого текста, который индексируется и в котором производится поиск, необходимо наличие возможности хранить в документе неограниченное количество других полей, которые хранят мета-информацию о документе, что необходимо для дальнейшей работы с результатами поиска. Очень желательно, чтобы количество и типы полей не ограничивались, а их индексируемость можно было настраивать. Например: в одном поле хранится название, во втором аннотация, в третьем ключевые слова, в четвёртом — идентификатор документа в вашей системе. Необходимо гибко настраивать область поиска (в каждом поле или только в указанных), а также те поля, которые будут извлекаться с базы поисковика и выдаваться с результатами поиска.
- платформа и язык — если вы собираетесь выделять поиск в отдельный от приложения модуль или сервер, или даже выносите его на отдельный сервер (железо в смысле), то роль платформы не такая и большая. Обычно это или C++ или Java.
- наличие встроенных механизмов ранжирования и сортировки — особенно хорошо, если поисковик можно расширять (и он написан на известном вам языке) и написать нужные вам реализации этих функций, ведь существует множество разных алгоритмов, и не факт, что используемый по умолчанию в поисковике вам подойдёт.
Теперь кратко расскажем о тех поисковых решениях, на которые вам следует обратить внимание, как только вы решите приступить к вопросу о поиске. Я намеренно не рассматриваю встроенные в вашу СУБД решение — FULLTEXT в MySQL и FTS в PostgreSQL. MySQL не может применяться для серьёзного поиска, особенно по большим объёмам данных, поиск в PostgreSQL намного лучше, но только если вы уже применяете эту базу. Хотя, как вариант — ставить отдельный сервер БД и там использовать только хранение данных и поиск тоже вариант.
Характеристики поисковых решений
Sphinx | Apache Lucene | Xapian | |
---|---|---|---|
Тип | отдельный сервер или MySQL storage engine | отдельный сервер или сервлет, встраиваемая библиотека | встраиваемая библиотека |
Платформа | C++ | Java (порты на PHP, C#/.NET, Perl, Ruby, Python) | C++ |
Индекс | монолитный + дельта-индекс, возможность распределённого поиска | инкрементный индекс, но требующий операции слияния сегментов (оптимизации) | инкрементный «живой» индекс, inmemory индексы для небольших баз. |
Варианты поиска | булевый поиск, поиск по фразам, учёт близости слов | булевый поиск, поиск по фразам, нечёткий поиск, учёт близости слов, поиск по маске | булевый поиск, поиск по фразам, поиск с ранжированием, поиск по маске, поиск по синонимам |
API и протоколы | SQL DB, собственный | Java API | С++, Perl API, Java JINI, Python, PHP, TCL, C# и Ruby, CGI интерфейс с XML/CSV форматом |
Поддержка языков | встроенный английский и русский стемминг, soundex для реализации морфологии | отсутствует морфология, есть стемминг (Snowball) и анализаторы для ряда языков (включая русский) | отсутствует морфология, есть стемминг для ряда языков (включая русский), проверка правописания в поисковых запросах |
Дополнительные поля документов | неограниченное количество | неограниченное количество | отсутствуют |
Форматы | только текст или SQL DB | текст, возможно индексация базы данных через JDBC | только текст |
Размер индекса/скорость | очень быстрый, индексация около 10 Мб/сек (зависит от CPU), поиск около 0.1 сек/~2 — 4 Гб индексе, поддерживает размеры индекса в сотни Гб и сотни миллионов документов, однако есть примеры работ на терабайтных базах данных. | около 20 Мб/минута, размер индексных файлов ограничен 2 Гб (на | тесты скорости на офф. сайте отсутствуют. Известны работающие инсталляции на 1.5 Тб индекса |
Лицензия | GPL 2 или коммерческая | Apache License 2.0 | GPL |
URL | sphinxsearch.com | http://lucene.apache.org/ | xapian.org |
Sphinx search engine
Sphinx, вероятно, самый мощный и быстрый из всех открытых движков, которые мы рассматриваем. Особенно удобен тем, что имеет прямую интеграцию с популярными базами данных и поддерживает развитые возможности поиска, включая ранжирование и стемминг для русского и английского языка. Похоже, что отличную поддержку русского языка проект имеет из-за того, что автор — наш соотечественник, Андрей Аксенов. Поддерживаются и нетривиальные возможности вроде распределённого поиска и кластеризации, однако фирменной фичей является очень и очень высокая скорость индексации и поиска, а также способность отлично утилизировать ресурсы современных серверов. Известны очень серьёзные инсталляции, содержащие терабайты данных, поэтому Sphinx вполне можно рекомендовать как выделенный поисковый сервер для проектов любого уровня сложности и объёма данных. Прозрачная работа с самыми популярными базами данных MySQL и PostgreSQL позволяет его использовать в обычном для веб-разработки окружении, к тому же сразу «из коробки» есть API для разных языков, в первую очередь, для РНР. Но сам поисковик необходимо компилировать и устанавливать отдельно, поэтому на обычном хостинге он неприменим — только VDS или собственный сервер, причём желательно побольше памяти. Индекс у поисковика монолитный, поэтому придётся немного «извратиться», настраивая дельта-индекс для корректной работы в случае, когда очень много новых или изменённых документов, хотя огромная скорость индексации позволяет организовать перестройку индекса по расписанию и это не скажется на работе собственно поиска.SphinxSE — это версия, функционирующая как движок хранения данных для MySQL (требует патча и перекомпиляции базы), Ultrasphinx — конфигуратор и клиент для Ruby (кроме присутствующего в дистрибутиве API), кроме этого есть плагины для многих известных CMS и блог-платформ, вики, которые заменяют стандартный поиск (полный список). Кстати, интересное обсуждение о выборе поисковика для Python веб-проекта.
Семейство Apache Lucene
Lucene — самый известный из поисковых движков, изначально ориентированный именно на встраивание в другие программы. В частности, его широко используют в Eclipse (поиск по документации) и даже в IBM (продукты из серии OmniFind). В плюсах проекта — развитые возможности поиска, хорошая система построения и хранения индекса, который может одновременно пополняться и оптимизироваться вместе с поиском. Доступен и параллельный поиск по множеству индексов с объединением результатов. Сам индекс построен из сегментов, однако для улучшения скорости рекомендуется его периодически оптимизировать. Изначально присутствуют варианты анализаторов для разных языков, включая русский с поддержкой стемминга (приведения слов к нормальной форме). Однако минусом является все же очень низкая скорость индексации (особенно в сравнении с Sphinx), сложность работы с базами данных и отсутствие API (кроме родного Java). И хотя для достижения серьёзных показателей Lucene может кластеризироваться и хранить индексы в распределённой файловой системе или базе данных, для этого требуется сторонние решения, так же как и для всех остальных функций — например, изначально он умеет индексировать только обычный текст. Но именно в плане использования в составе сторонних продуктов Lucene «впереди планеты всей» — ни один другой движок не имеет столько портов на другие языки. Одним из факторов такой популярности является и очень удачный формат файлов индексов, который используют сторонние решения.Solr — лучшее решение на базе Lucene, значительно расширяющее её возможности. Это самостоятельный сервер корпоративного уровня, предоставляющий широкие поисковые возможности в качестве веб-сервиса. Стандартно Solr принимает документы по протоколу HTTP в формате XML и возвращает результат также через HTTP (XML, JSON или другой формат). Полностью поддерживается кластеризация и репликация на несколько серверов, расширена поддержка дополнительных полей в документах (в отличие от Lucene, для них поддерживаются различные стандартные типы данных, что приближает индекс к базам данных), поддержка фасетного поиска и фильтрации, развитые средства администрирования, а также возможности кеширования и бекапа индекса в процессе работы. С одной стороны, это самостоятельное решение на базе Lucene, с другой — её возможности существенно расширены относительно базовых, поэтому если вам необходим отдельный поисковый сервер, обратите сперва внимание на Solr.
Nutch — второй известнейший проект на базе Lucene. Это веб-поисковый движок (поисковый механизм + веб-паук для обхода сайтов) совмещённый с распределённой системой хранения данных Hadoop. Nutch «с коробки» может работать с удалёнными узлами в сети, индексирует не только HTML, но и MS Word, PDF, RSS, PowerPoint и даже MP3 файлы (мета-теги, конечно), по сути — это полноценный поисковик-убийца Google. Шучу, расплата за это — значительное урезание функционала Lucene, например не поддерживаются булевые операторы в поиске, не используется стемминг. Если стоит задача сделать небольшой локальный поисковик по местным ресурсам или заранее ограниченному набору сайтов, при этом нужен полный контроль над всеми аспектами поиска, или вы создаёте исследовательский проект для проверки новых алгоритмов, в таком случае Nutch станет вашим лучшим выбором. Однако учтите его требования к аппаратной части и широком канале — для реального web-поисковика счёт трафика идёт на терабайты.
Вы думаете, никто Nutch не использует «по-взрослому»? Ошибаетесь — из самых известных проектов, о которых вы могли слышать, его использует поисковая система по исходным кодам Krugle.
Но не только за счёт проектов-надстроек известен и популярен Lucene. Будучи лидером среди открытых решений и воплотив в себя множество отличных алгоритмов, Lucene первый кандидат в портирование на другие платформы и языки. Сейчас имеются следующие порты (я имею ввиду те, что более-менее активно развиваются и максимально полные):
- Lucene. Net — полный порт Lucene, полностью алгоритмически, по классах и API идентичный перенос на платформу MS. NET/Mono и язык C#.
- Ferret — порт на язык Ruby
- CLucene — версия на языке С++, что обещает дать существенный прирост производительности. По некоторым тестам, он быстрее оригинала в
3–5 раз, а иногда и более (на индексации, поиск сравним или быстрее на всего5–10%). Оказалось, что эту версию использует большое количество проектов и компаний — ht://Dig, Flock, Kat (поисковик для KDE), BitWeaver CMS и даже такие компании, как Adobe (поиск по документации) и Nero. - Plucene — реализация на Perl
- PyLucene — реализация для Python-приложений, однако не полная и требует java
- Zend_Search_Lucene — единственный порт на язык РНР, доступный в составе Zend Framework.
Xapian
Xapian пока это единственный претендент на конкуренцию Lucene и Sphinx, выгодно отличается от них наличием «живого» индекса, не требующего перестройки при добавлении документов, очень мощным языком запросов, включая встроенный стемминг, проверку орфографии, и даже поддержку синонимов. Однако я не нашёл никакой информации о возможности добавлять к документам произвольные дополнительные поля и получать их с результатами поиска, поэтому связь системы поиска с вашей собственной может представлять определённые трудности. В пакет входит Omega — надстройка над библиотекой, которая готова для использования в качестве самостоятельного поисковика и как раз она отвечает за возможности индексации разных типов документов и CGI интерфейс.Наверное, на этом наш обзор можно завершить. Хотя существует ещё множество поисковых механизмов, на поверку часть из них является портами или надстройками над уже рассмотренными. Например, промышленного уровня поисковый сервер для собственной CMS компании eZ, ezFind на самом деле не отдельный поисковик, а интерфейс к стандартному Lucene Java и включает его в свою поставку. Это же касается и компонента Search из их пакета eZ Components — он предоставляет унифицированный интерфейс для доступа к внешним поисковым серверам. И даже такое интересное и мощное решение, как Carrot и SearchBox это серьёзно модифицированные версии той же Lucene, значительно расширенные и дополненные новыми возможностями. Самостоятельных же поисковых решений, с открытым кодом, которые полностью реализуют индексацию и поиск по собственных алгоритмах на рынке не так и много.
Выводы
Хотя окончательно принять решение, подходит или нет конкретный поисковик вашему проекту сможете только вы и, часто, лишь после детального исследования и тестов, однако некоторые выводы можно сделать уже сейчас.Sphinx подойдёт вам, если необходимо индексировать большие объёмы данных в базе MySQL и вам важна скорость индексации и поиска, однако не требуются специфические возможности поиска вроде «fuzzy search» и вы согласны выделить на это отдельный сервер или даже кластер.
Если необходимо встроить поисковый модуль в ваше приложение, то лучше всего поиска готовые порты для вашего языка к библиотеке Lucene — для всех распространённых языков они есть, однако могут реализовывать далеко не все возможности оригинала. Если же вы разрабатываете приложение на Java, то Lucene однозначно лучший выбор. Однако учтите достаточную медленную индексации и необходимость частой оптимизации индекса (и требовательность к CPU и скорости диска). Для РНР это, по всей видимости, единственный приемлемый вариант полной реализации поиска без дополнительных модулей и расширений.
Xapian достаточно хороший и качественный продукт, однако менее распространённый и гибкий, чем остальные. Для приложений на С++ и требованиями к широким возможностям языка запроса он будет лучшим выбором, однако требует ручной доводки и модификаций для встраивания в собственный код или использования как отдельного поискового сервера.
19 коментарів
Підписатись на коментаріВідписатись від коментарів Коментарі можуть залишати тільки користувачі з підтвердженими акаунтами.