Une raison quelconque n’utilise pas la recherche de texte intégral intégrée à PostgreSQL sur Heroku?

Je me prépare à déployer une application Rails sur Heroku qui nécessite une recherche en texte intégral. Jusqu’à présent, je l’exécutais sur un VPS utilisant MySQL avec Sphinx.

Cependant, si je veux utiliser Sphinx ou Solr sur Heroku, je devrais payer pour un add-on.

Je remarque que PostgreSQL (la firebase database utilisée sur Heroku) intègre une fonction de recherche de texte intégral.

Y a-t-il une raison pour laquelle je ne pouvais pas utiliser la recherche en texte intégral de Postgres? Est-ce plus lent que Sphinx ou existe-t-il une autre limitation majeure?

Edit, 2016 – Pourquoi pas les deux?

Si vous êtes intéressé par Postgres vs Lucene, pourquoi pas les deux? Découvrez l’extension ZomboDB pour Postgres, qui intègre Elasticsearch en tant que type d’index de première classe. Encore un projet assez précoce mais ça me semble très prometteur.

(Techniquement pas disponible sur Heroku, mais rest intéressant à regarder.)


Divulgation: Je suis un co-fondateur des add-ons Websolr et Bonsai Heroku, donc mon sharepoint vue est un peu biaisé envers Lucene.

Mon sharepoint vue sur la recherche de texte intégral Postgres est qu’il est assez solide pour les cas d’utilisation simples, mais il y a un certain nombre de raisons pour lesquelles Lucene (et donc Solr et ElasticSearch) est supérieur en termes de performances et de fonctionnalités.

Pour les débutants, jpountz fournit une excellente réponse technique à la question: pourquoi Solr est-il tellement plus rapide que Postgres? Cela vaut la peine de lire plusieurs fois pour vraiment digérer.

J’ai également commenté un épisode récent de RailsCast comparant les avantages et les inconvénients relatifs de la recherche de texte intégral de Postgres par rapport à Solr. Laissez-moi récapituler cela ici:

Avantages pragmatiques pour Postgres

  • Réutilisez un service existant que vous utilisez déjà au lieu de configurer et de maintenir (ou de payer) autre chose.
  • Bien supérieur à l’opérateur SQL LIKE incroyablement lent.
  • Moins de soucis en gardant les données synchronisées car elles sont toutes dans la même firebase database – aucune intégration au niveau de l’application avec certaines API de service de données externes.

Avantages pour Solr (ou ElasticSearch)

Au sumt de ma tête, sans ordre particulier…

  • Mettez à l’échelle votre charge d’indexation et de recherche séparément de votre charge de firebase database habituelle.
  • Analyse de termes plus flexible pour des choses comme la normalisation des accents, la formation linguistique, le N-grammes, la suppression des balises… Autres fonctionnalités intéressantes comme la vérification orthographique, l’extraction de contenu riche (PDF et Word, par exemple)
  • Solr / Lucene peut tout faire sur la liste de recherche en texte intégral de Postgres .
  • Un classement de pertinence beaucoup plus rapide et plus efficace, personnalisable efficacement au moment de la recherche.
  • Des performances de recherche probablement plus rapides pour les termes courants ou les requêtes compliquées.
  • Des performances d’indexation probablement plus efficaces que Postgres.
  • Meilleure tolérance aux modifications de votre modèle de données en dissociant l’indexation de votre magasin de données principal

Clairement, je pense qu’un moteur de recherche dédié basé sur Lucene est la meilleure option ici. Fondamentalement, vous pouvez considérer Lucene comme le référentiel open source de l’expertise de recherche.

Mais si votre seule autre option est l’opérateur LIKE , la recherche de texte intégral Postgres est une victoire définitive.

Depuis que je viens de faire l’effort de comparer la recherche élastique (1.9) contre le FTS postgres, j’ai pensé que je devais partager mes résultats car ils sont un peu plus actuels que ceux cités par @gustavodiazjaimes.

Mon principal souci avec postgres était qu’il n’y avait pas de facettes intégrées, mais c’est sortingvial de construire vous-même, voici mon exemple (dans django):

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

J’utilise postgres 9.6 et elastic-search 1.9 (via haystack sur django). Voici une comparaison entre elasticsearch et postgres sur 16 différents types de requêtes.

  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 

Afin d’obtenir des postgres à ces vitesses pour des recherches à facettes, j’ai dû utiliser un index GIN sur le champ avec un SearchVectorField, qui est spécifique au django mais je suis sûr que d’autres frameworks ont un type de vecteur similaire.

Une autre considération est que la page 9.6 supporte maintenant la correspondance de phrase, ce qui est énorme.

Ce que je retiens, c’est que Postgres est dans la plupart des cas préférable car il offre:

  1. stack plus simple
  2. pas de dépendances de wrapper api backend backend à gérer (think-sphinx, django-sphinx, haystack etc.). Celles-ci peuvent être un frein, car elles peuvent ne pas prendre en charge les fonctionnalités de votre moteur de recherche (par exemple, les facettes / agrégats de botte de foin).
  3. a des performances et des fonctionnalités similaires (pour mes besoins)

J’ai trouvé cette comparaison étonnante et je veux la partager:

Recherche en texte intégral dans PostgreSQL

Délai de construction de l’index Index LIKE – aucun
PostgreSQL / GIN – 40 min
Sphinx Search – 6 min
Apache Lucene – 9 min
Indice inversé – élevé

Indicateur de stockage d’index LIKE – aucun
PostgreSQL / GIN – 532 Mo
Sphinx Search – 533 Mo
Apache Lucene – 1071 Mo
Index inversé – 101 Mo

Query Speed ​​LIKE predicate – 90+ secondes
PostgreSQL / GIN – 20 ms
Sphinx Search – 8 ms
Apache Lucene – 80 ms
Index inversé – 40 ms

La recherche en texte intégral de Postgres offre des capacités incroyables dans les domaines de la recherche, du classement et du renforcement, de la gestion des synonymes, des recherches floues, etc.

Donc, si Postgres est déjà dans votre stack et que vous n’avez pas besoin de facettage, mieux vaut essayer l’énorme avantage de conserver les index en synchronisation et de conserver une stack élégante, avant de rechercher des solutions basées sur Lucene – du moins si tout est possible. votre application n’est pas basée sur une recherche.

La fonction FTS de Postgresql est mature et assez rapide pour les recherches. Ça vaut le coup de regarder.