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

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

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

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

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

5 ответов


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

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

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


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

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

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

Я также прокомментировал недавний эпизод 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. нет зависимостей оболочки api-интерфейса поиска для борьбы с (мышление-сфинкс, Джанго-сфинкс, стог сена и т. д.). Они могут быть перетаскиванием, так как они могут не поддерживать функции, которые делает ваш поисковый сервер (например, фасетирование/агрегаты сена).
  3. имеет аналогичную производительность и функции (для моих нужд)

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

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

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

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

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


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

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


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