web-dev-qa-db-fra.com

Une raison quelconque d'utiliser la recherche en texte intégral intégrée de 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'ai utilisé sur un serveur VPS utilisant MySQL avec Sphinx.

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

Je remarque que PostgreSQL (la base de données utilisée sur Heroku) possède une fonctionnalité intégrée de recherche en texte intégral.

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

54
Ethan

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 il me semble vraiment prometteur.

(Techniquement non disponible sur Heroku, mais qui mérite d'être regardé.)


Divulgation: Je suis cofondatrice des add-ons Websolr et Bonsai Heroku, mon point de vue est donc un peu biaisé en faveur de Lucene.

D'après ce que j'ai lu sur la recherche en texte intégral dans Postgres, elle est assez solide pour les cas d'utilisation simples, mais il existe plusieurs raisons pour lesquelles Lucene (et donc Solr et ElasticSearch) est supérieure tant en termes de performances que de fonctionnalités.

Pour commencer, jpountz fournit une réponse technique vraiment excellente à la question, Pourquoi Solr est-il tellement plus rapide que Postgres? Cela vaut la peine de lire deux ou trois lectures pour bien digérer.

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

Avantages pragmatiques pour Postgres

  • Réutilisez un service existant que vous utilisez déjà au lieu de configurer et de gérer (ou de payer) autre chose.
  • De loin supérieur à l’opérateur SQL LIKE, extrêmement lent.
  • Moins de problèmes de synchronisation des données puisque tout se trouve dans la même base de données - pas d'intégration au niveau de l'application avec certaines API de services de données externes.

Avantages de Solr (ou ElasticSearch)

De mémoire, sans ordre particulier…

  • Mettez à l'échelle votre charge d'indexation et de recherche séparément de votre charge de base de données normale.
  • Analyse des termes plus souple pour des choses comme la normalisation d'accent, la souche linguistique, les N-grammes, la suppression de balises… D'autres fonctionnalités intéressantes telles que la vérification orthographique, le «contenu riche» (par exemple, PDF et Word)
  • Solr/Lucene peut tout faire dans la liste TODO de la recherche en texte intégral Postgres .
  • Un classement de la pertinence par terme bien meilleur et plus rapide, personnalisable efficacement au moment de la recherche.
  • Probablement des performances de recherche plus rapides pour les termes courants ou les requêtes complexes.
  • Probablement une performance d'indexation plus efficace que Postgres.
  • Meilleure tolérance au changement dans 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. En gros, vous pouvez penser à Lucene en tant que référentiel open source de compétences en matière de recherche.

Mais si votre seule autre option est l'opérateur LIKE, la recherche en texte intégral de Postgres constitue un avantage certain.

60
Nick Zadrozny

Comme je viens de comparer la recherche élastique (1,9) à la post-FTS FTS, je me suis dit que je devrais partager mes résultats, car ils sont un peu plus récents que ceux mentionnés par @gustavodiazjaimes.

Mon souci principal avec postgres était de ne pas avoir de facettes intégrées, mais c'est simple à construire soi-même, voici mon exemple (sous 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 (avec haystack sur Django). Voici une comparaison entre elasticsearch et postgres à travers 16 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 ces vitesses pour les recherches à facettes, je devais utiliser un index GIN sur le champ avec SearchVectorField, qui est spécifique à 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.

Mon argument est que postgres est dans la plupart des cas préférable car il offre:

  1. pile plus simple
  2. pas de dépendances de backend api wrapper de recherche à gérer (think-sphinx, Django-sphinx, botte de foin, etc.). Celles-ci peuvent poser problème car elles risquent de 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)
19
yekta

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

Recherche en texte intégral dans PostgreSQL

Temps nécessaire pour construire le prédicat Index LIKE - aucun
PostgreSQL/GIN - 40 min
Recherche Sphinx - 6 min
Apache Lucene - 9 min
Index inversé - élevé 

Index Storage LIKE prédicat - aucun
PostgreSQL/GIN - 532 Mo
Sphinx Search - 533 MB
Apache Lucene - 1071 MB
Index inversé - 101 Mo 

Requête vitesse LIKE - 90 secondes et plus
PostgreSQL/GIN - 20 ms
Recherche de sphinx - 8 ms
Apache Lucene - 80 ms
Index inversé - 40 ms 

15

La recherche en texte intégral de Postgres offre des capacités étonnantes dans les domaines de la radicalisation, du classement/renforcement, de la gestion des synonymes, de la recherche floue, entre autres - mais ne prend pas en charge la recherche par facettes.

Donc, si Postgres est déjà dans votre pile et que vous n'avez pas besoin de facettes, essayez-le pour profiter de l'énorme avantage de pouvoir synchroniser facilement les index et de maintenir une pile élégante, avant de rechercher des solutions basées sur Lucene - du moins si tout votre application n'est pas basée sur la recherche.

2
Devi

La fonction FTS de Postgresql est mature et assez rapide lors des recherches. Ça vaut le coup d'oeil à coup sûr.

0
Scott Marlowe