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

Классификация

По области поиска (условно)

Локальные

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

Глобальные

Предназначены для поиска информации по всей сети Интернет либо по значительной её части. Представителями таких поисковых машин являются поисковые системы Google , Яндекс и т. п. Поисковые машины осуществляют поиск информации различного типа, например текстов, видео, изображений, географических объектов, персональных данных и др. При этом файлы, с которыми может работать поисковая машина, могут быть как текстового формата (например.html, .htm, .txt, .doc, .rtf…), так и графического (.gif, .png, .svg…) или мультимедийного (видео и звук). Пока наиболее распространённым является именно поиск по текстовым документам.

Поисковый запрос

Исходной информацией для поиска является поисковый запрос .

Функции

Поисковые машины выполняют несколько функций:

Поиск ссылок

Поиск ссылок на страницы и другие документы сайтов.

Автоматический

Ручной режим

Пользователи сами добавляют в базу данных поисковой машины ссылки на страницы своих сайтов

Индексация документов сайтов

Извлечение из документов информации, важной для поиска, преобразование этой информации в формат, удобный для поисковой машины и сохранение этой информации в базу данных поисковой машины

Поиск по базе данных проиндексированных документов

Может состоять из нескольких этапов

Нахождение документов, соответствующих поисковому запросу

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

Кластеризация документов

Примечания

См. также


Wikimedia Foundation . 2010 .

Смотреть что такое "Поисковая машина" в других словарях:

    Поисковая машина - (searching engine): веб сервер, проводящий индексацию веб страниц на доступных серверах (например, Yandex)... Источник: ИНТЕРНЕТ РЕСУРСЫ. ТРЕБОВАНИЯ ДОСТУПНОСТИ ДЛЯ ИНВАЛИДОВ ПО ЗРЕНИЮ. ГОСТ Р 52872 2007 (утв. Приказом Ростехрегулирования от… … Официальная терминология

    поисковая машина - Веб сервер, проводящий индексацию веб страниц на доступных серверах (например, Yandex). [ГОСТ Р 52872 2007] Тематики информационные технологии в целом EN searching engine … Справочник технического переводчика

    В Интернет специальный веб сайт, на котором пользователь по заданному запросу может получить ссылки на сайты, соответствующие этому запросу. Поисковая система состоит из трех компонент: 1 поискового робота; 2 индекса системы; и 3 программы,… … Финансовый словарь

    В Internet поисковая машина, которая: отсылает запрос на поиск в несколько поисковых систем; и генерирует из полученных ответов сводку (на одной странице). По английски: Meta search engine Синонимы: Мета гусеница Синонимы английские: Metacrawler… … Финансовый словарь

    Эта статья должна быть полностью переписана. На странице обсуждения могут быть пояснения. Поисковая система программно аппаратный комплекс с веб интерфейсом, предоставляющий возможност … Википедия

    Поисковая система - – (англ. search engine, синонимы: искалка, поисковый сервер, поисковая машина) – Инструмент для поиска информации в Интернете. Как правило, работа поисковой машины состоит из двух этапов. Специальная программа (поисковый робот, автомат, агент,… … Энциклопедический словарь СМИ - Поисковая система веб сайт, предоставляющий возможность поиска информации в Интернете. Большинство поисковых систем ищут информацию на сайтах Всемирной паутины, но существуют также системы, способные искать файлы на ftp серверах, товары в… … Википедия

Книги

  • К вопросу об эффективности поиска конкретики в Интернете , И. А. Семёнов. Согласно исследованиям Berkley, объём информации в Интернете по состоянию на 2003 год оценивался в 258, 85 терабайта, и это только общедоступные данные. По данным Internet World Stats, рост… электронная книга

С самого появления цифровых фотоаппаратов у нас, конечно, нет недостатка в фотографиях. На самом деле, Yahoo ! оценивает, что в 2014 году мы получим 880 миллионов цифровых фотографий.

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

Конечно, это может зависеть от вида изображения, которое вы ищете. Если вы ищете какой-то часто фотографируемый объект, например, компьютеры, книги или цветы, вам не придется долго искать, в вашем распоряжении десятки хороших фото.

В то же время, попробуйте задать на поиск какой-то менее распространенный объект или, например, абстрактное понятие — возможно, солнечный день или конкретный тип цветка. Это может оказаться гораздо сложнее. Часть трудностей связана с тем, что даже если существует идеальное изображение, оно не может быть помечено таким образом, чтобы его можно было найти.

В этих случаях вы можете потратить много времени на поиски на различных сайтах с бесплатными изображениями и все равно остаться ни с чем. Ох. Это объясняет, почему так много коммерческих хранилищ рекламируются на бесплатных сайтах изображений — их поисковые средства часто стоят того, чтобы заплатить за рекламу.

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

Системы поиска бесплатных изображений

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

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

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

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

Таким образом, я не буду сравнивать качество поиска этих 7 сервисов — я просто приведу мои впечатления от работы с ними, а также некоторые общие факты, такие, как количество фотографий, которые они включают в поиск, или количество проиндексированных ими сайтов.

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

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

1. Google Images

Для многих из нас, Google Images является первым (и часто единственным ) выбором для поиска бесплатных изображений, которые также разрешены для коммерческого использования. Для поиска бесплатных изображений через Google Images введите ключевые слова в поле поиска и нажмите Enter , затем выберите вкладку Картинки (1):

Google Images

Затем нажмите на кнопку «Инструменты поиска » (2), чтобы открыть список параметров поиска и выберите пункт «Права использования » (3). Из выпадающего меню выберите лицензию, которая подходит именно Вам.

Выбор Google для поиска, как правило, хорош. Для действительно популярных терминов вы найдете огромное количество изображений. К счастью, они часто предлагают суб-результаты. Например, для компьютеров они предлагают такие категории, как Apple , ноутбуки, картинки, обои, запчасти, PNG и т.д., чтобы конкретизировать поиск.

Для менее популярных терминов и менее ограничительных прав использования, выбор не так широк. Очень часто вы не найдете ничего подходящего, особенно если ищете материал, который является бесплатным для повторного использования с возможностью или без возможности вносить изменения. В этом случае вам стоит попробовать другой сервис для поиска изображений, из тех, что я опишу ниже. Это не займет много времени.

2. CC Search

CC Search , (сокращенно от Creative Commons Search ), это еще один крупный поисковик изображений, лицензированных в соответствии с лицензиями Creative Commons .

Хотя, как они сами утверждают, технически это не поисковая система, но они явно предлагают результаты поиска по нескольким другим сайтам, таким как Europeans , Flickr , Google Images , Wikimedia Commons , Fotopedia , Open Clipart Gallery , Pixabay :


Проблема состоит в том, что CC Search не ищет по всем этим сайтам сразу. Вместо этого, вы вводите поисковый запрос и выбираете место, где хотите искать. Это не очень удобно, но все же быстрее, чем искать непосредственно на всех этих сайтах.

Кроме изображений CC Search предлагает результаты по музыке, видео и другим медиа.

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

Если вам понравился CC Search , и вы планируете использовать его постоянно, они предлагают браузерное дополнение (по крайней мере, для Firefox ), которое помогает ускорить доступ к сайту.

Имейте в виду, что Creative Commons не означает «бесплатно для всех ». Вы должны понимать, что использование данной лицензии подразумевает размещение всех ссылок, аккредитацию и другие условия.

3. Photo Pin

Flickr — это, пожалуй, крупнейшее хранилище бесплатных картинок в Интернете, поэтому не удивительно, что несколько сервисов поиска изображений концентрируются исключительно на нем. Photo Pin — один из них. Когда вы открываете сайт и вводите запрос, вы видите что-то вроде этого:


На левой стороне вы можете выбрать тип нужной вам лицензии (например, коммерческая или некоммерческая ), а также каким образом сортировать результаты (новые сначала, актуальность, интересность ).

Конечно, нет никаких причин, почему бы вам не поискать Creative Commons контент непосредственно на Flickr через расширенный поиск. Однако Photo Pin обеспечивает вам два преимущества.

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

Действительно удобный сервис.

4. PicFindr

В отличие от многих других сервисов, называющих себя «поисковиками», даже если они ищут только по Flickr , PicFindr более амбициозен. Он производит поиск более чем по десяти сайтам бесплатных изображений в широком диапазоне лицензий (Creative Commons, GNU и другие ).

Список сайтов включает в себя бесплатные подразделы некоторых сайтов изображений, например, DreamsTime , что делает эту поисковую систему особенно полезной. Когда вы вводите поисковый запрос, вы увидите что-то вроде этого:


Кроме того, PicFindr имеет некоторые дополнительные опции поиска, которые делают его еще более полезным:


Некоторые из сайтов, включенных в поиск, не слишком известны, в то же время некоторые из популярных сайтов почему-то отсутствуют, но в целом, это очень хорошая поисковая система.

5. Veezzle

Если вы готовы попробовать еще один поисковик, который ищет как по Flickr , так и по Wikimedia Commons , познакомьтесь с Veezzle . Когда вы заходите на сайт и вводите поисковый запрос, вы можете конкретизировать его, как это показано на следующем скриншоте:


Когда вы нажимаете кнопку «Поиск «, результаты из Flickr и Wikimedia Commons отображаются отдельно. Вы можете выбрать, как вы хотите выводить результаты — по релевантности, по популярности или по дате загрузки.

Несмотря на то, Veezzle является еще одной поисковой системой, работающей с Flickr , не отвергайте этот вариант, прежде чем попробуете в его в действии. Flickr настолько огромен и разнообразен, что различные поисковые системы могут выдавать вам различные результаты. Так что, возможно, с помощью Veezzle вы найдете как раз самые подходящие вам изображения.

6. Every Stock Photo

С возможностью выбирать из почти 23 миллионов бесплатных фотографий Every Stock Photo является действительно прекрасным местом для поиска. Данный сервис производит поиск по нескольким сайтам. В дополнение к Flickr и Wikimedia Commons , которые охвачены в других поисковиках, Every Stock Photo ищет и в других местах: MorgueFile , SXU , НАСА и Photi :


Расширенные опции позволяют оптимизировать поиск. Они позволяют выбрать тип лицензии, источник и что отображать (разрешение, лицензия, источник ). Для меня лично, Every Stock Photo является вторым после Google Images предпочтительным поисковиком изображений. Но, так как вкусы у всех разные, не обязательно, что он подойдет для остальных:


7. Behold

Вполне возможно, что уже приведенных поисковых систем вам окажется более чем достаточно, но вот последний. По сравнению с некоторыми другими поисковыми системами Behold кажется бедным родственником, так как он выводит результаты только с Flickr . Тем не менее, в отличие от тех же поисковых систем Behold очень, очень быстрый, что является огромным преимуществом.

  • Индексы можно создавать только на полях MyISAM-таблиц.
  • Размер индекса - примерно половина от размера данных. Правда, нужно иметь ввиду, что отключить сохранение самих текстов вы не можете, поэтому к этим 50 % нужно добавить ещё 100 % - данные-то хранятся.
  • Скорость индексации - в чистом виде приличная, примерно 1.5 МБ/с. Понятно, что ещё нужно прогонять через стеммер. Если наполнять индекс, на ходу вытаскивая данные из той же базы, и прогоняя через Perl-порт русского Snowball-стеммера - получается 314 КБ/с. На самом деле в MySQL есть архитектура для подключения стеммеров плагинами («fulltext parser plugins»), вот только самих плагинов как-то нет… :)
  • Встроенного стеммера нет, стоп-слова вшиты английские, свои добавить нельзя. По умолчанию булев поиск идёт по «ИЛИ», поэтому для поиска по «И» нужно каждое слово превращать в «+слово».
  • Есть два режима - булев и обычный («natural language») поиск. Булев поиск просто проверяет, есть ли слова в документе и поддерживает логические операции, фразы и префиксный поиск, но не возвращает оценку релевантности (только 0 или 1). Обычный поиск умеет релевантность, но не умеет операторы. Поэтому, чтобы поддерживать и то, и другое - нужно дёргать один и тот же запрос в двух режимах.
    • Префиксный поиск в MySQL феерически медленный. На нескольких словах, развёрнутых в префиксы, легко может получиться и 15, и 40 секунд. Так что его не нужно использовать вообще.
  • По нескольким полям одновременно искать не умеет - то есть, синтаксис-то такой MATCH() позволяет, но никакой оптимизации поиска при этом не происходит, а происходит фулскан. Поэтому лучше писать (select id where match(field1) ...) UNION (select id where match(field2) ...) .
  • Скорость поиска, по запросам, взятым из заголовков случайных багов, с лимитом количества найденного 1000:
    • В 5 потоков на 3 словах - в среднем 175 мс, максимум 3.46 сек.
    • В 5 потоков на 3 словах, первые 10 результатов - так же.
    • В 5 потоков на 2 словах - в среднем 210 мс, максимум 3.1 сек.
    • В 1 поток на 3 словах - в среднем 63 мс, максимум 764 мс.
    • Зависит в основном от количества найденного.
  • Основное достоинство - наличие поиска «искаропки».

Sphinx (2.0.1-beta)

  • Отдельный поисковый сервер. Интерфейсные библиотеки к нему есть для кучи разных языков. Очень прикольно, что в 0.9.9, кроме «родного» интерфейса, появился SphinxQL - SQL-интерфейс к Sphinx’у по протоколу MySQL, то есть, с использованием обычных MySQL-клиентов.
  • Изначально обновляемых (realtime) индексов в сфинксе не было, единственное, что он умел - это построить индекс целиком и потом по нему искать.
  • Не умеет нормально обновлять/удалять документы в индексе до сих пор, нормально только добавляет. Удаление производится установкой флажка «старая запись», и последующим её удалением из всех результатов поиска каждый раз.
  • Realtime индексы поддерживают не всё - например, не поддерживают префиксы/инфиксы и MVA.
  • Немножко бардак с интерфейсами и фичами: обновление реалтайм индекса только через SphinxQL; синтаксис поиска во всех трёх интерфейсах разный (обычный, SphinxQL, SphinxSE); штук 5 режимов поиска, из которых 4 obsolete; indexer не может перестраивать реалтайм индексы; TRUNCATE индекса через SphinxQL сделать нельзя, посмотреть, сколько в индексе записей, тоже нельзя…
  • На этом недостатки заканчиваются - есть сервер поиска, с которым можно общаться по собственному протоколу или протоколу MySQL, куча разных возможностей, индексирует и ищет очень быстро, размер индекса - примерно 1/3 данных. Может увеличиться раза в 2, если включить индексацию точных словоформ.
  • Встроены русский, английский и чешский стеммеры и препроцессоры Soundex и Metaphone (для сравнения английских слов по звучанию). Стеммеры для других языков можно тоже подключить, только нужно собирать с ключиком --with-libstemmer . Поддержка стоп-слов, разумеется, есть. Синонимы тоже, причём есть обычные, а есть «tokenizing exceptions», которые могут включать в себя спецсимволы. Также есть «blend_chars » - символы, которые одновременно считаются и разделителями, и входящими в слова - например, чтобы «AT&T» превратилось в слова «AT», «T» и «AT&T».
  • Из прикольных необычных фич - умеет инфиксный поиск (для тех, кто хотел быстро искать по подстроке!), многозначные поля (MVA), умеет индексировать по абзацам и предложениям и даже по содержимому заранее заданных HTML-тегов. Также может подсвечивать искомые слова в цитатах и многое другое. Правда, MVA и инфиксы не поддерживаются (пока что?) в обновляемых индексах.
  • Индексация очень быстрая - чистая скорость с реалтайм индексом 6.7 МБ/с (загрузка SQL-дампа), с обычным индексом - вообще 12 МБ/с (загрузка xmlpipe2 -дампа). «Нечистая» скорость (из Perl’а, с вычиткой данных на лету из MySQL) - 4.5 МБ/с. С инфиксами всё, естественно, сильно замедляется - 440 КБ/с, куча ввода-вывода - 10.5 ГБ, и индекс получается 3 ГБ размером на 330 МБ данных.
  • Поиск вообще реактивный:
    • В 5 потоков на 3 словах - в среднем 7 мс, максимум 75 мс.
    • В 5 потоков на 2 словах - в среднем 7 мс, максимум 81 мс.
    • В 5 потоков на 3 словах, первые 10 результатов - в среднем 5 мс, максимум 57 мс.
    • В 1 поток на 3 словах - в среднем 2 мс, максимум 35 мс.

Xapian (1.2.6)

  • Библиотека, готового сервера поиска нет. C++ API довольно вменяемое. Конкурентную работу вроде поддерживает (много читателей, один писатель).
  • Куча доступных биндингов под разные языки: C++, Java, Perl, Python, PHP, Tcl, C#, Ruby, Lua.
  • Индекс - инвертированный на основе B-дерева.
  • Круто то, что Xapian не обязательно использовать именно как полнотекстовый индекс - по сути, это просто реализация инвертированного индекса, которую можно использовать как в голову взбредёт, потому что ограничений на «слова», содержащиеся в документе, нет, кроме ограничения длины 245 байтами. По идее, можно его использовать в качестве БД.
  • Откровенно хреновая документация. Какое-то сборище кусочков информации, в котором ещё и не всё есть. Чтобы понять какие-то моменты, приходится тупо лазать в код. Я обнаглел и поставил баг даже на эту тему - баг 564 . Ну а что, правда - движок-то вроде неплохой, но мало кто о нём знает.
  • Забавно, что начав его тестировать, нашёл странный баг - сегфолт в libuuid , не позволяющий создать базу, если параллельно загружен Image::Magick . Оказалось, что это даже не баг ImageMagick’а, а ещё серьёзнее - это баг libc6 ! В 2.12 и 2.13 поломана инициализация Thread-Local Storage при динамической загрузке библиотек, о как. В 2.14 пофикшено, но в дебиане-то пока 2.13. Поставил в дебиан баг 637239 (там же есть ссылки на баги в gentoo и самой libc).
  • Perl-биндинги требуют допиливания для возможности выбора бэкенда, а по умолчанию не новейший Brass, а стабильный Chert. Допиливание лёгкое. На эту тему я тоже поставил им баг - баг 565 .
  • Поддержки разных полей в индексе как бы нет, но она делается добавлением в начало каждого слова префиксов: http://xapian.org/docs/omega/termprefixes.html
    • Это «официальный подход», Xapian его умеет сам, только префиксы укажи.
    • Такой подход имеет как минимум один небольшой недостаток - по умолчанию запрос не ищет по всем полям, а чтобы искал по всем, нужно руками вставлять в запрос OR.
    • Да, документация опять неполная и не там, где надо - должна быть в мануале Xapian’а, а она - в мануале Omega, которая являет собой готовый простенький CGI-поисковичок.
    • Неприятный момент - быстренько нашёл баг в парсере запросов - он неправильно генерирует термины для поиска основ слов в полях (которые с префиксами). Индексатор ко всем основам в начале приписывает префикс «Z», то есть основа для слова «идея» в заголовке (скажем, префикс T) проиндексируется как «ZTиде». А парсер запросов пытается искать по «Tиде» и, естественно, ничего не находит. Поставил им на эту тему баг 562 . Фиксится, на самом деле, одной строчкой.
  • Стеммеры есть встроенные для 15 языков, как обычно, сгенерённые из Snowball "а. Есть поддержка стоп-слов (разумеется) и синонимов. Ещё интереснее - оно может исправлять опечатки без использования словарей, а лишь на основе индексированных данных (должно включаться настройкой). То есть, например, для «Xapain» оно честно подскажет «Xapian». Ещё есть поддержка поиска по «недовведённому запросу», то есть, для подсказок при вводе запроса побуквенно. По сути, это просто добавление * к последнему слову в поиске, но с учтёнными нюансами синтаксиса запросов.
  • Ещё есть «Faceted Search» - подсчёт агрегатных значений по всем или почти всем найденным документам (скажем, с лимитом в 10000). То есть, эти 10000 документов вам возвращены не будут, но будут проверены и по ним будет подсчитано какое-то агрегатное значение. Например, таким образом можно выдать 10 результатов (страницу) и одновременно ответить на вопрос «из каких категорий найдены документы».
  • Паршиво, что если при индексации раз в 256 багов делать flush() (commit), то скорость с ~1.5 МБ/с снижается до 412 КБ/с, причём, сильно возрастает количество операций ввода- вывода - раз в 10-20. В принципе, это заявлено и логично для любого инвертированного индекса - гораздо оптимальнее накапливать изменения, чем пытаться обновлять по одному, ибо количество обновляемых лексем возрастает.
  • Размер индекса - пишут, что примерно равен размеру данных, это не так, реально больше раза в 2. Пишут, если не хранить позиции слов в документах, станет в 2 раза меньше. Но извините, Sphinx тоже хранит позиции, а индекс у него в 2 раза меньше данных. Если прогнать xapian-compact (дефрагментация БД) - индекс таки да, уменьшается, но всё равно остаётся где-то в 1.7 раза больше данных.
    • Ага, причина найдена - Xapian всегда индексирует и основы, и точные формы слов. Отключить индексацию точных форм нельзя, обидно, поставил на эту тему им баг 563 .
  • Ищет быстро. Тестировал так: искал по нескольким соседним словам длиной не меньше 2 символов, в режиме STEM_ALL, взятым из заголовков багов (искал не по «ИЛИ», а «И»), причём каждое слово заменял на (слово OR title:слово OR private:слово) , то есть на поиск по трём полям вместо одного, ограничивал количество результатов 1000.
    • В 5 потоков на 3 словах - в среднем 14 мс, максимум 135 мс.
    • В 5 потоков на 2 словах - в среднем 29 мс, максимум 137 мс.
    • В 5 потоков на 3 словах, первые 10 результатов - в среднем 2 мс, максимум 26 мс.
    • В 1 поток на 3 словах - в среднем 7 мс, максимум 51 мс.
    • Скорость поиска зависит в основном от количества найденных результатов, чем больше - тем дольше ищет.

Xapian имеет 3 backend’а (реализации самого индекса) - в порядке новизны Flint, Chert и Brass. Это как в Debian’е oldstable, stable и testing:) в 1.2.x бэкенд по умолчанию - Chert. До Flint’а ещё был Quartz.

PostgreSQL Textsearch (9.1)

  • Индекс - инвертированный на основе GIN (обобщённый инвертированный индекс - Generalized Inverted iNdex). Раньше назывался Tsearch2 , создан Олегом Бартуновым и Фёдором Сигаевым.
  • Есть встроенные стеммеры, поддержка стоп-слов, синонимов, тезауруса (что-то типа словаря понятий, заменяет слова на другие «предпочитаемые»), словарей ISpell (хотя они, говорят, жутко тормозят при инициализации).
  • Есть возможность при индексации прицепить к каждой лексеме «вес», который на самом деле не «вес», а аналог Xapian-префикса, то есть, название поля, из которого лексема пришла. Таких «весов» может быть всего 4 - A, B, C, D, и в дальнейшем их можно использовать при поиске. Пример построения tsvector "а из двух полей с «весами»: setweight(to_tsvector(coalesce(title,"")), "A") || setweight(to_tsvector(coalesce(keyword,"")), "B") .
  • Есть отдельные функции для ранжирования результатов и подсветки искомых слов в цитатах. Ранжировать можно, присваивая численные веса «весам» ABCD, указанным выше (которые «поля»). Причём по умолчанию веса равны {0.1, 0.2, 0.4, 1.0}.
  • Индексируемый тип данных называется tsvector (text search vector). PostgreSQL позволяет создавать функциональные индексы, и в мануале по умолчанию предлагают создавать именно их - CREATE INDEX i ON t USING gin(to_tsvector(<поле>)) . Так вот: не надо так делать! А то очень неприятно удивитесь скорости запросов. Обязательно создавайте отдельную колонку типа tsvector , складывайте в неё свои tsvector "ы, и создавайте индекс на ней.
    • Объясняю, почему: функция ранжирования результатов отдельная, и тоже работает с tsvector "ом. Если он не хранится, то должен вычисляться на лету при каждом запросе для каждого документа, а это очень хреново влияет на производительность, особенно, когда запрос находит много документов. То есть, если в запрос тупо включить сортировку по релевантности - ORDER BY ts_rank(to_tsvector(field), ) DESC - будет гораздо медленнее MySQL’я:).
    • Заодно, в качестве оптимизации дискового пространства, можно не хранить полный текст документов в индексе.
  • Из операторов поиска - AND, OR и NOT и префиксный поиск. Поиска близлежащих слов, точных форм, фраз нет.
  • Размер индекса - где-то 150 % от размера данных, если сами тексты не хранить, а хранить только tsvector "ы.
  • Скорость индексации - пока данных мало, 1.5 МБ/с, с ростом индекса потихоньку падает, но если сами тексты не хранить, то, вроде, устаканивается. На всё тех же данных багзиллы получилось в среднем 522 КБ/с, хотя к концу индексации было меньше, чем в начале.
  • Скорость поиска:
    • В 5 потоков на 3 словах - в среднем 28 мс, максимум 2.1 сек.
    • В 5 потоков на 2 словах - в среднем 54 мс, максимум 2.3 сек.
    • В 5 потоков на 3 словах, первые 10 результатов - в среднем 26 мс, максимум 611 мс.
    • В 1 поток на 3 словах - в среднем 10 мс, максимум 213 мс.

Lucene , Solr (3.3)

  • Lucene - это Java-библиотека поиска (не сервер), заобзорить и протестировать её полностью очень сложно - движок самый мощный (но и самый монструозный) из всех рассмотренных.
  • То, что это библиотека, написанная на Java, является её главным недостатком - обращаться к Java из других языков сложно, поэтому и у Lucene с интерфейсами проблемы:(. Производительность от Java, возможно, тоже несколько страдает, но скорее всего очень некритично.
    • Из биндингов к языкам есть только вполне живой PyLucene - в Python-процесс подсаживается JVM с Lucene на борту, а некий JCC обеспечивает взаимодействие. Но я бы сильно подумал, нужно ли использовать такую комбинацию…
  • Для поправки ситуации есть Solr - уже всё-таки поисковый сервер, реализованный в виде веб-сервиса с XML/JSON/CSV-интерфейсами. Для запуска требует servlet-контейнер - Tomcat , или чтобы попроще - Jetty . Вот с ним уже можно работать из многих языков.
  • Заявлено, что скорость индексации Lucene «типа, очень большая», больше 20 МБ/с, памяти при этом, типа, требуется очень мало (от 1 МБ), а инкрементальная индексация (по одному документу) такая же быстрая, как и индексация множества документов разом. Размер индекса заявлен 20-30 % от размера данных.
  • Lucene очень расширяемая, поэтому есть куча различных фич и приблуд, особенно в сочетании Solr’а с другими библиотеками:
    • 31 встроенный стеммер , куча анализаторов - обрабатывающих звучание (Soundex, Metaphone и вариации), аббревиатуры, стоп-слова, синонимы, «protect-слова» (обратное стоп-словам), словосочетания, шинглы, разделение слов (Wi-Fi, WiFi -> Wi Fi), URL’ы, и так далее, множество различных вариантов генерации запросов (например, FuzzyLikeThisQuery - поиск по «запросу, похожему на заданный»).
    • Репликация индексов, автоматическая кластеризация (группировка) результатов поиска (Carrot2), поисковый робот (Nutch), поддержка разбора бинарных документов (Word, PDF и т.п) с помощью Tika .
    • Есть даже приблуда для «поднятия» заданных результатов по заданным запросам независимо от нормального ранжирования (здравствуй, SEO).
    • И даже это ещё не всё.
  • Размер индекса совершенно Lucene’ский - 20 % от данных. Скорость индексации Solr’ом по 256 документов за запрос, без промежуточных коммитов, у меня получилась 2.75 МБ/с, а с коммитами раз в 1024 документа - 2.3 МБ/с. Если не коммитить, то памяти кушает больше - у меня в районе 110 МБ resident, если коммитить - 55 МБ.
  • Скорость поиска Solr:
    • В 5 потоков на 3 словах - в среднем 25 мс, максимум 212 мс.
    • В 5 потоков на 2 словах - в среднем 35 мс, максимум 227 мс.
    • В 5 потоков на 3 словах, первые 10 результатов - в среднем 15 мс, максимум 190 мс.
    • В 1 поток на 3 словах - в среднем 11 мс, максимум 79 мс.

2.3.3.4, Lucene++ 3.0.3.4

  • Lucene написана на Java, и поэтому есть некоторое количество портов её на разные языки, наиболее живые из которых - это C++ и C# порты - , Lucene++ и Lucene.NET . Есть и другие порты, но они (полу)заброшенные и/или нестабильные.
  • С CLucene тоже не всё идеально:
    • Развивается медленнее Lucene - в то время, как Lucene уже 3.3, CLucene стабильный (0.9.2.1) всё ещё соответствует Lucene 1.9, и в нём даже нет стеммеров, а CLucene «тестируемый» - Lucene 2.3.
    • Биндингов к языкам мало / устаревшие, например Perl-биндинги поддерживают только 0.9.2.1. Называется «Write Your Own». Потратив пару часов, я их запатчил (поставив баг авторам) и даже добавил поддержку стеммеров, которые в 2.3, к счастью, всё-таки есть. Вообще сыроваты эти биндинги, я вот уже ещё один сегфолт выловил и запатчил.
    • По-видимому, есть баги, документация в интернете устаревшая (но можно сгенерировать doxygen’ом из исходников нормальную), хостится на SourceForge, на котором всё медленно и грустно, а багтрекер время от времени сам закрывает баги (если на них никто не реагирует O_O).
  • По фичам - большая часть фич Lucene в портах есть. Фич всяких Solr’ов, естественно, нет.
  • Скорость индексации CLucene - у меня получилась 3.8 МБ/с. Не 20+ заявленных Lucene, но это же со стеммером и через Perl-интерфейс, так что весьма неплохо.
  • Размер индекса, как и у Lucene/Solr, получился примерно 20 % от размера данных - это и рекорд среди всех движков, и соответствует заявленным 20-30 %!
  • Lucene++ отличается от CLucene следующим:
    • Реализация полнее и новее (3.0.3.4), например, есть анализаторы под разные языки со вшитыми стоп-словами.
    • Lucene++ везде использует shared_ptr (автоматический подсчёт ссылок на объекты с помощью C++-шаблонов). Причём это очень конкретно заметно даже при компиляции, очень уж она долго происходит по сравнению с CLucene.
    • С биндингами ещё хуже, чем в CLucene - есть только полудохлые под питон , сгенерённые SWIG "ом - то есть, наверняка текут как сволочи и вообще неизвестно, работают ли. Хотя мне, честно говоря, сходу даже не очень понятно, как нормально сделать Perl-биндинги к этим shared_ptr’ам.
    • Lucene++, по-видимому, используют совсем мало, судя по тому, что в баг-трекере всего 9 багов.
  • Скорость поиска - замеры аналогично замерам Xapian, только с использованием MultiFieldQueryParser вместо замены слов на дизъюнкции:
    • В 5 потоков на 3 словах получается в среднем 10 мс, максимум 212 мс.
    • В 5 потоков на 2 словах - в среднем 19 мс, максимум 201 мс.
    • В 5 потоков на 3 словах, первые 10 результатов - в среднем 3 мс, максимум 26 мс.
    • В 1 поток на 3 словах - в среднем 4 мс, максимум 39 мс.
    • Зависит опять-таки в основном от количества найденного, что соответствует заметке о сложности поиска .

Для тех, кто в танке

  • Инвертированный индекс - сопоставляет каждому слову набор документов, в которых оно встречается, в отличие от прямого индекса, который документу сопоставляет набор слов. Практически все движки полнотекстового поиска используют именно инвертированные индексы, ибо искать по ним быстро, хотя обновлять тяжелее, чем прямые.
  • Стеммер - от английского слова «stem» - основа слова. Откусывает от слов окончания, делая из них основы. Предназначен для того, чтобы по слову «кошка» нашлись и «кошки», и «кошку», и так далее. Snowball - DSL для написания стеммеров.
  • Стоп-слова - список очень часто употребляемых слов (предлогов-союзов и т. п.), индексировать которые нет смысла, потому что значения они содержат мало и встречаются почти везде.
  • Позиционная информация - позиции слов в документах, сохраняемые в индексе, для дальнейшего поиска фраз или просто слов, расположенных друг от друга не дальше, чем на …
  • Префиксный поиск (слов*) - поиск слов, начинающихся на заданное (например, кошк*). Иногда называется Wildcard-поиском, но строго говоря, Wildcard-поиск - это поиск слов, начинающихся на заданный префикс и оканчивающихся на заданный суффикс (например, ко*а - найдёт и слово «кошка», и «коала»).
  • Багзилла - open-source баг-трекер, используемый у нас в компании, на содержимом которого тестировался поиск.

Сравнительная таблица

MySQL PostgreSQL Xapian Sphinx Solr CLucene
Скорость индексации 314 КБ/с 522 КБ/с 1.36 МБ/с 4.5 МБ/с 2.75 МБ/с 3.8 МБ/с
Скорость поиска 175 мс / 3.46 сек 28 мс / 2.1 сек 14 мс / 135 мс 7 мс / 75 мс 25 мс / 212 мс 10 мс / 212 мс
Размер индекса 150 % 150 % 200 % 30 % 20 % 20 %
Реализация СУБД СУБД Библиотека Сервер Сервер Библиотека
Интерфейс SQL SQL API API, SQL Веб-сервис API
Биндинги 9 6 + ∀ 8 3.5
Операторы поиска &*" &* &*"N-~ &*"N- &*"N-~ &*"N-~
Стеммеры Нет 15 15 15 31 15 + CJK
Стоп-слова, синонимы Нет Да Да Да Да Да
Soundex Нет Нет Нет Да Да Нет
Подсветка Нет Да Нет Да Да Да

Ранжирование результатов и сортировка по разным полям есть везде.

Дополнительно:

Заключение

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

Тоже быстрый, очень фичастый, эффективный и расширяемый, но не самый простой в использовании движок - Lucene. Главная проблема с интерфейсами - либо Java, либо C++ порты и проблемы с биндингами. То есть, если вы пишете не под Java, C++, Python или Perl, надо использовать Solr. Solr памяти уже немножко кушает, индексирует и ищет чуть помедленнее, может быть неудобен как отдельный Java-сервер в сервлет-контейнере, но зато имеет огромную кучу разных возможностей.

Xapian… Ищет шустро, индексирует не очень, и сам индекс получается великоват. Его плюс - куча интерфейсов под разные языки (C++, Java, Perl, Python, PHP, Tcl, C#, Ruby, Lua). Если появится режим для отключения индексации точных форм - размер индекса раза в 2 сразу уменьшится.

Если вы уже используете PostgreSQL и готовы мириться с не очень высокой скоростью индексации и полным отсутствием хитрых операторов поиска, то вполне можно использовать Textsearch, потому что ищет он быстрее MySQL и вполне сравнимо с остальными. Но нужно помнить о том, что индекс обязательно создавать на реальной колонке типа tsvector , а не на выражении to_tsvector() .

MySQL FULLTEXT тоже можно использовать в простых случаях, когда база небольшая. Но ни в коем случае не делать MATCH(несколько полей) и ни в коем случае не использовать префиксный поиск.

Любые правки этой статьи будут перезаписаны при следующем сеансе репликации. Если у вас есть серьезное замечание по тексту статьи, запишите его в раздел «discussion» .

Технические проблемы создания поискового движка сайта

    Создание полноценного поискового движка сайта по сложности, стоимости и срокам превосходит создание большого сайта.

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

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

    Действительно, можно скачать и установить на сайте форму, позволяющую вводить в нее информацию и выдающую упорядоченный набор информации и ссылок. Но назвать эту форму поисковым движком сайта еще нельзя. Практически во всех случаях релевантность , полнота и точность выдаваемых результатов очень низкая. Вместо положительного эффекта от установки поискового движка получается отрицательный эффект.

    Распространение таких поисковых движков - дань моде. Заказчик хочет иметь поисковый движок. Не зная, как оценить результаты работы поискового движка, он не может понять, насколько эффективна его работа.

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

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

Пример

    Сайт посвящен веб-дизайну. Основное внимание уделяется вопросам создания сайта и редизайну. На сайте много раз встречается фраза "создание сайта", но нет фраз "изготовление сайта" и "разработка сайта".

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

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

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

Пример 2

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

    Посетитель может подразумевать "веб-дизайн", но запрашивать другие слова: веб-студия, веб студия, вебстудия, вэб-студия, вэб студия, вэбстудия, web студия, webстудия, веб-мастеринг, студия веб-дизайна, студия дизайна и т.д. Если указанных слов на сайте нет, поисковый движок сообщит, что результатов не найдено.

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

Пример 3

    Тот же сайт и тот же поисковый движок.

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

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

На заметку:

    Примеров некорректной работы поисковых движков каждый опытный пользователь Интернет может привести множество.

    Не случайно, алгоритм работы поисковой системы и рейтинг, который она выстраивает на основе запроса, учитывает и анализирует многие параметры .

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

    Естественно, что при создании большинства бизнес-сайтов, с бюджетом до $ 40 000 - $ 50 000, ручная доводка поисковых движков - дело невыгодное.

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

Резюме

    Создание полноценного поискового движка сайта по сложности, стоимости и срокам превосходит создание большого сайта.

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

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

Привет хабр.
Пару месяцев назад мне поступил заказ на разработку сайта. Сайт представлял собой сборник статей добавляемых пользователем. Одним из пунктов технического задания было создание поиска. Т.к. я большой любитель изобретать велосипеды, было решено не использовать поиск от Яндекса или гугла.

Обычный поиск

Самым тривиальным решением было разбивать статьи на слова, разбивать запрос на слова и искать совпадения.
Плюсы:

  • Высокая скорость. Можно было для этого использовать сразу mysql таблицу со словами
  • Простота. Скрипт для такого алгоритма занимал бы всего несколько десятков строк.
  • низкая точность, отсутствие возможности исправления ошибок

Нечёткий поиск

Итак, было решено сделать все как у «взрослых». Т.е. авто исправление ошибок и поиск не только по точному соответствию слов но и по формам слова. Т.к. хотелось большей производительности, поиск писался не на php, а на Яве постоянно висящей в памяти и хранящей индекс статей.

Стеммер

Для начала надо было определиться, как обобщать разные формы одного слова. Будем считать, что одинаковые слова это слова с одинаковым корнем. Но вот извлечение корня это не лёгкая задача. Решая эту проблему, я быстро нагуглил так называемый «стеммер Поттера» (Сайт автора). Стеммер Поттера выделяет корень слова, который, однако, не всегда совпадает с лексическим. К тому же он написан для разных языков, в том числе и для русского. Однако пример русского написан на пхп и, переписав его один в один на яву, я получил очень слабую производительность. Проблема решилась использованием регулярных выражений. Из-за нелюбви к регулярным выражениям я взял готовый пример www.algorithmist.ru/2010/12/porter-stemmer-russian.html (Спасибо автору).
В результате производительность получилась на уровне 1 млн. слов в секунду.

Исправление опечаток

Часто бывает так, что пользователь ошибается при вводе запроса. Поэтому нам необходим алгоритм определения похожести слов. Для этого существует много методов, но самым быстрым из них является метод 3-грамм. Суть его такова: Разбиваем слово на тройки последовательно идущих букв. Со вторым поступаем аналогично. Пример:
Конституция => КОН ОНС НСТ СТИ ТИТ ИТУ ТУЦ УЦИ ЦИЯ
Консттуция=> КОН ОНС НСТ СТТ ТТУ ТУЦ УЦИ ЦИЯ

Потом сравниваем эти тройки и чем больше одинаковых троек мы получили, тем выше похожесть слов.
Итого у нас совпадает 6 троек из 8 или 75%.
Этот метод хорош, когда в запросе пропущена или добавлена лишняя буква. Но вот когда человек заменяет одну букву на другую, у нас сразу попадает 3 тройки. Однако обычно лишняя или пропущенная буква это опечатка. А вот заменённая - это орфографическая ошибка. Какие же это ошибки:

  • Замена а – о и о-а: мАлоко, пАбеда, рОдон
  • Е-и, и-е. бИда, пЕрог
  • неправильно употребление мягкого и твёрдого знака.

Поэтому приведём все к одному виду:

Private String replace(String word) { word=word.replace("а","о"); word=word.replace("е","и"); word=word.replace("б","п"); word=word.replace("д","т"); word=word.replace("г","к"); word=word.replace("щ","ш"); word=word.replace("ъ","ь"); word=word.replace("ж","ш"); return word; }

Таким образом, нам надо перебрать все имеющиеся слова и найти самое похожее. При 1 млн. слов это около 1 с, что не приемлемо. Оптимизируем. Для начала, положим, что нас интересуют слова, отличающиеся в длине максимум на 2 буквы. Потом заметим, что из трёх букв существует всего 30 000 вариаций.(33*33*33).Поэтому прохешируем ещё на этапе индексации итого алгоритм будет такой:

String gramms=get3gram(word); int i=0; for (String gram:gramms) { if (this.tgram_abc[i]==null) this.tgram_abc[i]=new ArrayList(); this.tgram_abc[i].add(id); i++; }

Далее сделаем аналогичное для слова с «приведёнными» буквами, потом заменим нн на н и добавим в третий массив, и напоследок удалим все мягкие знаки.
Теперь можно искать похожие слова. Разбиваем слова на граммы, находим хеш кажой тройки и получаем списко слов в которых одни есть на похожих позициях.

HashMap GramBalls=new HashMap(); int StartG=(i-2>=0)?i-2:0; int EndG=(i+2); for (int l=len-2;l<=len+2;l++) for (int j=StartG;j<=EndG;j++) if (this.tgram_abc[l][j]!=null) for (int id:this.tgram_abc[l][j]) if (!GramBalls.containsKey(id)) GramBalls.put(id, (1-(double)Math.abs(len-l)/3) /(word.length()-2));

В последней строке выведенная методом «тыка» формула, которая означает, что триграмм в конце будет приносить слову 0.7 очков/кол-во триграмма. А первая будет приносить 1 очко/кол-во грамм.
Дальше аналогично ищем для «приведённого» слова из запроса и для слова с заменёнными нн и мягкими знаками. Правда там вместо 1 будет 0.7 и 0.3 соответственно.
После сортируем слова по очкам и выбираем слово с наибольшим кол-вом очков. Однако если у «чемпиона» меньше 0.1 очка то возвращаем null. Это нужно чтобы не учитывать совсем непохожие слова. Т.к. приведённый выше алгоритм определяет что «космонавт» «астма» имеют похожесть 0.05.

Механизм индексации

У «взрослых» индексацией занимаются специальные программы пауки, которые периодически обходят сайты, индексируют содержимое, ищут ссылки на странице и идут по ним дальше. У нас же все просто. При добавлении страницы php скрипт посылает запрос нашем поисковику индексировать страницу. Далее страница очищается от тегов. После разбивается на слова. После этого определяется язык слова. Мы проходим по слову и для каждой буквы добавляем балл языкам, которые поддерживают это символ. Для русского это а-я и дефис «-».Для английского это a-z, дефис и апостроф(‘). Все символы и цифры вынесены в отдельный «символьный язык».
Для хранения и быстрого поиска у нас существует массив списка слов.

ArrayList WordIndex[язык текста][служебный индекс текста][язык слова]

Этот список хранит позицию слова в статье и id статьи.
Аналогично заводим массив для хранения корней слова.
Далее берем заголовок и индексируем его как ещё один текст.

Механизм поиска и ранжирования

Это самый главный механизм любой поисковой системы. Именно от того насколько правильно он создаёт выдачу зависит мнение пользователей.
Когда пользователь нажимает на кнопку поиск php скрипт пересылает запрос поисковику. Тот его разбивает на слова. Только тут есть одно отличие от индексации. Если при добавленной статьи при встрече незнакомого слова мы добавляем его в список слов, то при встрече в запросе незнакомого слова мы ищем наиболее похожее используя метод 3 грамм.
После разбиения для каждого слова мы получаем список из пар id текста – вхождение слова.
Определим, насколько статья подходит запросу:

  1. Посчитаем, сколько всего слов из запросов есть в статье.(a)
  2. Посчитаем, сколько всего корней из запросов есть в статье.(b)
  3. Посчитаем сколько существует словосочетаний слов аналогичных словосочетаниям в запросе(c)
  4. Посчитаем, сколько существует словосочетаний корней аналогичных словосочетаниям в запросе(d)
  5. Определим сколько слов из запроса встречаются в статье(e)
  6. Определим сколько корней из запроса(f)

После чего каждой статье добавим баллы по след формуле:

Math.log(2*a+1)+ Math.log(2+1)+2+Math.log(c*5+1))+ Math.log(d*3+1)))*(f+2*e));

Формула создана по след принципам:

  1. Слова приоритетнее корней
  2. Словосочетания приоритетнее обычных слов
  3. Чем более полно статья описывает поисковый запрос, тем выше её рейтинг. Причём полнота является ключевым

Далее пройдёмся по заголовкам, только там будем умножать баллы на 10, т.к. заголовок отражает суть статьи.
Сортируем и выводим.
Приведённый алгоритм обрабатывает 100 запросов в секунду при индексе в 1000 статей на VPS с процессором 1Ггц.
P.S. Эта статья лишь служит лишь для ознакомления с некоторыми алгоритмами и идеями нечёткого поиска.