Любая причина не использовать встроенный полнотекстовый поиск PostgreSQL на Heroku?
Я готовлюсь развернуть приложение Rails на Heroku, которое требует полнотекстового поиска. До сих пор я запускал его на VPS, используя MySQL с Sphinx.
Однако, если я хочу использовать Sphinx или Solr на Heroku, мне нужно будет заплатить за дополнение.
Я заметил, что PostgreSQL (БД, используемая в Heroku) имеет встроенную возможность полнотекстового поиска.
Есть ли причина, по которой я не смог использовать полнотекстовый поиск Postgres? Это медленнее, чем сфинкс или есть какое-то другое серьезное ограничение?
5 ответов
Редактировать, 2016 - Почему не оба?
Если вы заинтересованы в Postgres vs. Lucene, то почему не оба? Проверьте расширение ZomboDB для Postgres, которое интегрирует Elasticsearch как первоклассный индексный тип. Все еще довольно ранний проект, но он выглядит действительно многообещающим для меня.
(Технически не доступно на Heroku, но все же стоит посмотреть.)
Раскрытие информации: я являюсь соучредителем надстроек Websolr и Bonsai Heroku, поэтому моя точка зрения немного смещена в сторону Lucene.
Мое чтение по полнотекстовому поиску в Postgres заключается в том, что он довольно полезен для простых случаев использования, но есть ряд причин, по которым Lucene (и, следовательно, Solr и ElasticSearch) превосходят как с точки зрения производительности, так и функциональности.
Для начала, jpountz дает действительно превосходный технический ответ на вопрос: почему Solr намного быстрее, чем Postgres? Это стоит пару прочтений, чтобы действительно переварить.
Я также прокомментировал недавний эпизод RailsCast, в котором сравнивались относительные преимущества и недостатки полнотекстового поиска Postgres по сравнению с Solr. Позвольте мне повторить это здесь:
Прагматические преимущества для Postgres
- Повторно используйте существующий сервис, который вы уже используете, вместо того, чтобы настраивать и поддерживать (или оплачивать) что-то другое.
- Значительно превосходит фантастически медленный SQL
LIKE
оператор. - Меньше хлопот, связанных с синхронизацией данных, поскольку все они находятся в одной базе данных - нет интеграции на уровне приложений с некоторыми API внешних служб данных.
Преимущества для Solr (или ElasticSearch)
С макушки головы, без определенного порядка...
- Масштабируйте свою индексацию и поисковую нагрузку отдельно от обычной загрузки базы данных.
- Более гибкий анализ терминов для таких вещей, как нормализация акцента, лингвистическая обработка, N-граммы, удаление разметки… Другие интересные функции, такие как проверка орфографии, извлечение "богатого контента" (например, PDF и Word)…
- Solr / Lucene может делать все что угодно в списке TODO полнотекстового поиска Postgres.
- Намного лучший и быстрый рейтинг релевантности терминов, эффективно настраиваемый во время поиска.
- Вероятно, более высокая производительность поиска по общим терминам или сложным запросам.
- Вероятно, более эффективная производительность индексирования, чем Postgres.
- Повышенная устойчивость к изменениям в вашей модели данных путем отделения индексации от основного хранилища данных
Ясно, что я думаю, что выделенная поисковая система на основе Lucene является лучшим вариантом здесь. По сути, вы можете думать о Lucene как о де-факто репозитории с открытым исходным кодом для поисковых систем.
Но если ваш единственный другой вариант LIKE
оператор, то Postgres полнотекстовый поиск является определенным выигрышем.
Поскольку я только что попытался сравнить упругий поиск (1.9) с postgres FTS, я решил, что должен поделиться своими результатами, поскольку они несколько более свежие, чем те, которые цитирует @gustavodiazjaimes.
Моя основная проблема с postgres заключалась в том, что в нем не было встроенной огранки, но это тривиально, чтобы построить себя, вот мой пример (в django):
results = YourModel.objects.filter(vector_search=query)
facets = (results
.values('book')
.annotate(total=Count('book'))
.order_by('book'))
Я использую Postgres 9,6 и эластичный поиск 1,9 (через стог сена на Django). Вот сравнение упругого поиска и postgres по 16 различным типам запросов.
es_times pg_times es_times_faceted pg_times_faceted
0 0.065972 0.000543 0.015538 0.037876
1 0.000292 0.000233 0.005865 0.007130
2 0.000257 0.000229 0.005203 0.002168
3 0.000247 0.000161 0.003052 0.001299
4 0.000276 0.000150 0.002647 0.001167
5 0.000245 0.000151 0.005098 0.001512
6 0.000251 0.000155 0.005317 0.002550
7 0.000331 0.000163 0.005635 0.002202
8 0.000268 0.000168 0.006469 0.002408
9 0.000290 0.000236 0.006167 0.002398
10 0.000364 0.000224 0.005755 0.001846
11 0.000264 0.000182 0.005153 0.001667
12 0.000287 0.000153 0.010218 0.001769
13 0.000264 0.000231 0.005309 0.001586
14 0.000257 0.000195 0.004813 0.001562
15 0.000248 0.000174 0.032146 0.002246
count mean std min 25% 50% 75% max
es_times 16.0 0.004382 0.016424 0.000245 0.000255 0.000266 0.000291 0.065972
pg_times 16.0 0.000209 0.000095 0.000150 0.000160 0.000178 0.000229 0.000543
es_times_faceted 16.0 0.007774 0.007150 0.002647 0.005139 0.005476 0.006242 0.032146
pg_times_faceted 16.0 0.004462 0.009015 0.001167 0.001580 0.002007 0.002400 0.037876
Чтобы получить postgres к этим скоростям для фасетного поиска, мне пришлось использовать индекс GIN для поля с SearchVectorField, которое специфично для django, но я уверен, что другие фреймворки имеют похожий векторный тип.
Еще одно соображение - pg 9.6 теперь поддерживает сопоставление фраз, что огромно.
Мой вывод заключается в том, что postgres в большинстве случаев будет предпочтительнее, поскольку он предлагает:
- более простой стек
- нет зависимостей поискового бэкенда для API-оболочки (с которыми мы думаем - сфинкс, джанго-сфинкс, стог сена и т. д.). Это может быть перетаскивание, так как они могут не поддерживать функции, которые поддерживает ваш поисковый сервер (например, гранение / агрегаты стога сена).
- имеет аналогичные характеристики и характеристики (для моих нужд)
Я нашел это удивительное сравнение и хочу поделиться им:
Полнотекстовый поиск в PostgreSQL
Время строить индекс как предикат - нет
PostgreSQL / GIN - 40 минут
Поиск сфинкса - 6 мин
Apache Lucene - 9 минут
Инвертированный индекс - высокий
Индексное хранилище как предикат - нет
PostgreSQL / GIN - 532 МБ
Поиск Сфинкса - 533 МБ
Apache Lucene - 1071 МБ
Инвертированный индекс - 101 МБ
Предикат скорости запроса LIKE - более 90 секунд
PostgreSQL / GIN - 20 мс
Поиск сфинкса - 8 мс
Apache Lucene - 80 мс
Инвертированный индекс - 40 мс
Полнотекстовый поиск в Postgres обладает удивительными возможностями в области определения границ, ранжирования / повышения, обработки синонимов, нечеткого поиска среди других, но не поддерживает граненый поиск.
Так что, если Postgres уже находится в вашем стеке и вам не нужны фасеты, лучше попробуйте его, чтобы воспользоваться ОГРОМНЫМ преимуществом простоты синхронизации индексов и поддержания гладкого стека, прежде чем искать решения на основе Lucene - по крайней мере, если все Ваше приложение не основано на поиске.
Функция FTS в Postgresql является зрелой и довольно быстрой при поиске. Стоит посмотреть наверняка.