LINUX.ORG.RU
решено ФорумTalks

Полнотекстовый поиск

 , , , ,


1

0

Есть известные системы для реализации такого поиска: apache lucene (solr, elasticsearch), sphinx; ну и остальные, мне неизвестные, а значит ненужные.

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

В основе развития событий лежит, ну давайте, высоконагруженный проект рода и пола твиттера с более сложным бизнесом внутри и, соответственно, ряд дебильных вопросов:
— В каком виде хранятся индексы?
— Каковы основные этапы оптимизации поисковых движков при линейном росте содержимого/нагрузок?
— Последний вопрос забыл, подскажите? :)

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



Последнее исправление: NiceForce (всего исправлений: 1)

Много букв написал, хотя суть вопроса можно было выразить в 2,5 строчки.

В каком виде хранятся индексы?

В случае ES и SOLR - в формате файлов lucene. Lucene - это мощная библиотека для написания поисковых движков, а не реализация этого самого движка.
Скачай и запусти ES, создай индекс по мануалу у них на сайте и затем найди файлы индекса в файловой системе. И всё как бы станет понятно.
При шардинге индекса на деле создаются несколько «подиндексов» и поиск в них идёт параллельно, а результаты затем объединяются.
При наполнении индекса, в нём создаются «сегменты» — ещё более мелкие подиндексы, того же формата. Со временем, сегменты объединяются. Сегментация нужна, т.к. обновление целого индекса — ресурсоёмкая операция.
Так же следует помнить, что чем больше индексов (шард, сегментов - не важно), тем больше отжирается RAM, и тем быстрее идёт поиск в больших коллекциях. Но если индексов (сегментов, шард) слишком много, то это тоже тормозит поиск.

В случае ES, индекс — это виртуальная сущность, которая указывает на подиндексы (шарды), которые содержат подиндексы «сегменты», в которых уже идёт поиск. Lucene как раз отвечает за наполнение сегментов данными индексации. Таким образом, шарда, содержащая данные, содержит хотя бы один сегмент. А индекс содержит хотя бы одну шарду. Когда делаешь запрос — поиск идёт в сегментах шард.


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

Каковы основные этапы оптимизации поисковых движков при линейном росте содержимого/нагрузок?

Да особо никаких. Они не тормозят, если не искать по стоп-словам, контроллировать шардинг индексов, и никогда не искать по wildcard'ам («вас* люб* машу*»). Затраты будут на запил орфографии и синонимов, фасетов и прочих потребностей энтерпрайза перекроют любое желание оптимизации. При росте нагрузки и для отказоустойчивости системы используется репликация шард.

shahid ★★★★★
()
Последнее исправление: shahid (всего исправлений: 2)
Ответ на: комментарий от shahid

Сфинкс написан на плюсах человеком с терминальной стадией синдрома NIH

drF_ckoff ★★
()

Эээ, а как относятся школьники к остальным тегам?

goingUp ★★★★★
()

Мы с мускуля переехали на перкону. Там полнотекстовый поиск что называется из коробки. Им и пользуемся.

ppy ★★★
()
Ответ на: комментарий от NiceForce

Ещё касательно оптимизации: есть проблемы long-tail'а в инвертированных индексах. Это когда очень редкие термы, по которым скорее всего НЕ будут искать никогда, заметно удлиняют количество ключей в индексе, что, в свою очередь, пропорционально сказывается на оперативке.

Содержимое long-tail'а — например какие-нить слова с опечатками, числа, абракадабры, примеры стойких паролей с проиндексированных форумов и их md5/sha512-хешей, технические маркировки моделей продуктов (в случае индексирования интернет-магазинов). Подобный набег на RAM очень существенен при росте разнородности данных, а это очень больно ударяет по кошельку. Такие термы выявляются (по частотам встречаемости в корпусе и регэкспом /слова с цифрами/), а затем или срезаются (путём сильного расширения списков стоп-слов), или токинизируются на куски, или как-то ещё нормализуются/трансформируются в более простые и частые термы.

shahid ★★★★★
()
Последнее исправление: shahid (всего исправлений: 2)
Ответ на: комментарий от goingUp

А нельзя как-то сказать Solr/ES, чтобы убрал из индекса термы, которые встречаются всего 1 раз?

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

1. Все lucene-фильтры накладываются на индексируемую информацию только при инзерте этой самой информации в индекс. К моменту, когда информация уже залита в ES/Solr-индекс, оригинал документа может уже не существовать, т.к. они не обязаны сохранять исходник индексируемого документа (это задается в настройках индекса). Для переиндексации (пересохранения) надо иметь исходник документа на руках.

2. Любая смена конфигурации фильтров уже заполненного индекса (кроме добавления новых фильтров) вызовет ошибку ещё до начала выполнения, т.к. получится, что все данные индекса устарели и становятся несовместимыми с конфигурацией. Fatal error, rollback. Почему это происходит? Потому что конфигурация фильтров индекса накладывается не только на документы, но и на все поисковые запросы к этому индексу (это тоже можно отключить, только поиск работать не будет).

3. Допустим, конфигурация фильтров изменилась. Обновление целого индекса наживую («ребилд индекса», «reindex») — это перезаливка всех документов в индекс, а это создаст в существующем индексе новые сегменты, содержащие все данные предыдущих сегментов внутри себя (ибо существующие сегменты - не изменяемы). Т.е. получается как бы два индекса внутри одного, пока не вызвать оптимизацию, которой понадобится в несколько раз больше времени, чтобы вычистить старые сегменты, выяснить какие документы должны остаться, а какие должны быть вычищены и т.д. Оптимизация блокирует индекс на некоторое время, зависящее от iops'ов винча и размеров RAM.

Иными словами - при изменении конфигурации индекса (в частности, настроек вышеупомянутого фильтра стоп-слов), надо создать новый индекс, в него заливать новую конфигурацию, включать bulk indexing, затем заливать все доки, отключать bulk indexing, оптимизировать индекс, и в конце пути дропнуть старый индекс. Для небольшого облегчения этого процесса в elasticsearch есть алиасы. Автоматизация этого процесса небезопасна, т.к. появление нового индекса удваивает потребление RAM, а оптимизация целого индекса - ещё хлеще. Может вылететь OutOfMemory, если сильно не повезёт.

Определить неправославные термы можно через Map-reduce-задачу подсчета слов.

shahid ★★★★★
()
Последнее исправление: shahid (всего исправлений: 2)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.