Любая причина не использовать встроенный полнотекстовый поиск PostgreSQL на Heroku?



Я готовлюсь развернуть приложение Rails на Heroku, которое требует полнотекстового поиска. До сих пор я запускал его на VPS, используя MySQL с Sphinx.



однако, если я хочу использовать Sphinx или Solr на Heroku, мне нужно будет заплатить за дополнение.



Я заметил, что PostgreSQL (БД, используемая на Heroku) имеет встроенную возможность полнотекстового поиска.



есть ли причина, по которой я не мог использовать полнотекстовый поиск Postgres? Это медленнее, чем Сфинкс или есть какой-то другой крупной ограничение?

802   5  

5 ответов:

Edit, 2016-почему не оба?

если вы заинтересованы в Postgres против Lucene, почему бы не оба? Проверьте ZomboDB расширение для Postgres, которое интегрирует Elasticsearch как тип индекса первого класса. Все еще довольно ранний проект, но он выглядит действительно многообещающим для меня.

(технически недоступно на Heroku, но все же стоит посмотреть на.)


раскрытие информации: я соучредитель Websolr и бонсай Heroku дополнения, так что моя точка зрения немного смещена в сторону Lucene.

мое чтение в полнотекстовом поиске Postgres заключается в том, что он довольно прочен для простых случаев использования, но есть ряд причин, по которым Lucene (и, следовательно, Solr и ElasticSearch) превосходит как по производительности, так и по функциональности.

для начала jpountz обеспечивает действительно отличный технический ответ на вопрос, почему Solr намного быстрее, чем Postgres? стоит пару раз прочитать, чтобы действительно переварить.

Я также прокомментировал a недавний эпизод RailsCast сравнение относительных преимуществ и недостатков полнотекстового поиска Postgres по сравнению с Solr. Позвольте мне повторить это здесь:

прагматические преимущества для Postgres

  • повторно использовать существующую службу, которую вы уже работает вместо того, чтобы настраивать и поддерживать (или платить за) что-то еще.
  • намного превосходит фантастически медленный SQL LIKE оператора.
  • меньше хлопот с синхронизацией данных, так как все они находятся в одной базе данных - нет интеграции на уровне приложений с некоторыми внешними API службы данных.

преимущества для Solr (или ElasticSearch)

С моей головы, без особого порядка...

  • масштабирование индексации и поисковая нагрузка отдельно от обычной загрузки базы данных.
  • более гибкий анализ терминов для таких вещей, как нормализация акцента, лингвистическое стеммирование, N-граммы, удаление разметки... другие интересные функции, такие как проверка орфографии, извлечение "богатого контента" (например, PDF и Word)...
  • Solr / Lucene может делать все на список задач полнотекстового поиска Postgres просто отлично.
  • гораздо лучше и быстрее срок релевантности рейтинга, эффективно настраивается при поиске время.
  • вероятно, более высокая производительность поиска для общих терминов или сложных запросов.
  • вероятно, более эффективная производительность индексирования, чем Postgres.
  • лучший допуск для изменения в вашей модели данных путем отсоединения индексирования от вашего основного хранилища данных

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

но если ваш единственный другой вариант-это LIKE оператор, тогда полнотекстовый поиск Postgres-это определенная победа.

моя главная проблема с postgres заключалась в том, что у него не было встроенного фасетирования, но это тривиально, чтобы построить себя, вот мой пример (в django):

results = YourModel.objects.filter(vector_search=query)
facets = (results
    .values('book')
    .annotate(total=Count('book'))
    .order_by('book'))

Я использую postgres 9.6 и elastic-search 1.9 (через стог сена на django). Вот такое сравнение между elasticsearch и 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 в большинстве случаев будет предпочтительным как он предлагает:

  1. проще стек
  2. нет поиска backend api wrapper зависимостей для борьбы с (мышление-сфинкс, Джанго-сфинкс, стог сена и т. д.). Они могут быть перетаскиванием, так как они могут не поддерживать функции, которые делает ваш поисковый сервер (например, фасетирование/агрегаты haystack).
  3. имеет аналогичную производительность и функции (для моих нужд)

Я нашел это удивительное сравнение и хочу поделиться им:

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

время для построения индекса, как предикат - нет
PostgreSQL / GIN -- 40 мин
Поиск Сфинкса -- 6 мин
Apache Lucene -- 9 мин
Инвертированного индекса-высокая

хранение индекса как предикат -- none
PostgreSQL / GIN -- 532 MB
Поиск Сфинкса -- 533 MB
Apache Lucene -- 1071 MB
Инвертированный индекс -- 101 МБ

скорость запроса, как предикат -- 90 + секунд
PostgreSQL / GIN -- 20 ms
Поиск Сфинкса -- 8 мс
Apache Lucene -- 80 ms
Инвертированный индекс-40 мс

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

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

функция FTS Postgresql является зрелой и довольно быстрой при поиске. Это стоит посмотреть наверняка.

Comments

    Ничего не найдено.