elasticsearch vs MongoDB pour l'application de filtrage [fermé]

180

Cette question consiste à faire un choix architectural avant de plonger dans les détails de l'expérimentation et de la mise en œuvre. Il s'agit de l'adéquation, en termes d'évolutivité et de performances, d'elasticsearch par rapport à MongoDB, dans un but quelque peu spécifique.

En théorie, les deux stockent des objets de données qui ont des champs et des valeurs et permettent d'interroger ce corps d'objets. Donc, vraisemblablement, filtrer des sous-ensembles d'objets en fonction de champs sélectionnés ad hoc, est quelque chose qui convient aux deux.

Mon application tournera autour de la sélection d'objets selon des critères. Il sélectionnerait des objets en filtrant simultanément par plus d'un seul champ, en d'autres termes, ses critères de filtrage de requête comprendraient généralement entre 1 et 5 champs, peut-être plus dans certains cas. Alors que les champs choisis comme filtres seraient un sous-ensemble d'un plus grand nombre de champs. Imaginez quelque 20 noms de champs existants, et chaque requête est une tentative de filtrer les objets par quelques champs sur ces 20 champs globaux (il peut y avoir moins ou plus de 20 noms de champs globaux existants, je viens d'utiliser ce nombre pour démontrer le rapport de champs aux champs utilisés comme filtres dans chaque requête discrète). Le filtrage peut se faire par l'existence des champs choisis, ainsi que par les valeurs des champs, par exemple en filtrant les objets qui ont le champ A, et leur champ B est compris entre x et y,

Mon application fera en permanence ce type de filtrage, alors qu'il n'y aurait rien ou très peu de constante quant aux champs utilisés pour le filtrage à tout moment. Peut-être que dans elasticsearch, les index doivent être définis, mais peut-être que même sans index, la vitesse est au même niveau que celle de MongoDB.

Selon les données entrant dans le magasin, il n'y a pas de détails particuliers à ce sujet. Les objets ne seraient presque jamais modifiés après avoir été insérés. Peut-être que les anciens objets devraient être supprimés, j'aimerais supposer que les deux magasins de données prennent en charge la suppression de données en interne ou par une requête créée par l'application. (Moins fréquemment, les objets qui correspondent à une certaine requête devraient également être supprimés).

Qu'est-ce que tu penses? Et avez-vous expérimenté cet aspect?

Je m'intéresse aux performances et à l'évolutivité de celui-ci, de chacun des deux data stores, pour ce genre de tâche. C'est le genre de question de conception architecturale, et les détails des options spécifiques au magasin ou des pierres angulaires de la requête qui devraient le rendre bien architecturé sont les bienvenus comme démonstration d'une suggestion entièrement réfléchie.

Merci!

matanster
la source
Je ne sais pas pourquoi cela continue de recevoir des votes, est-ce que ce sont des options si importantes après si longtemps?
matanster
8
juste intéressant qu'avez-vous choisi il y a 6 ans et quelle était votre expérience jusqu'à présent :)?
Arūnas Smaliukas
8
MISE À JOUR - Pour ceux qui sont curieux de savoir si cette réponse est toujours pertinente, MongoDB dispose désormais d'index de texte intégral pour fournir les mêmes fonctionnalités et avantages que la recherche élastique a été décrite dans la réponse sélectionnée. Ils sont stockés en tant qu'index séparés et peuvent être interrogés si nécessaire, mais vous ne perdez aucun des avantages d'avoir une base de données à usage général. J'utilise MongoDB à des fins générales et pour les requêtes de recherche de texte depuis l'année dernière et je le recommande vivement. Juste mes deux cents.
Jason Roell

Réponses:

391

Tout d'abord, il y a une distinction importante à faire ici: MongoDB est une base de données à usage général, Elasticsearch est un moteur de recherche de texte distribué soutenu par Lucene. Les gens ont parlé d'utiliser Elasticsearch comme base de données à usage général, mais savent que ce n'était pas sa conception originale. Je pense que les bases de données NoSQL à usage général et les moteurs de recherche sont destinés à la consolidation, mais dans l'état actuel des choses, les deux proviennent de deux camps très différents.

Nous utilisons à la fois MongoDB et Elasticsearch dans mon entreprise. Nous stockons nos données dans MongoDB et utilisons Elasticsearch exclusivement pour ses capacités de recherche en texte intégral. Nous envoyons uniquement un sous-ensemble des champs de données mongo que nous devons interroger à Elastic. Notre cas d'utilisation diffère du vôtre en ce que nos données Mongo changent tout le temps: un enregistrement, ou un sous-ensemble des champs d'un enregistrement, peut être mis à jour plusieurs fois par jour, ce qui peut nécessiter une réindexation de cet enregistrement sur Elastic. Pour cette seule raison, utiliser Elastic comme unique magasin de données n'est pas une bonne option pour nous, car nous ne pouvons pas mettre à jour les champs sélectionnés; nous aurions besoin de réindexer un document dans son intégralité. Ce n'est pas une limitation élastique, c'est ainsi que fonctionne Lucene, le moteur de recherche sous-jacent derrière Elastic. Dans votre cas, le fait que les records aient gagné ' t être changé une fois enregistré vous évite d'avoir à faire ce choix. Cela dit, si la sécurité des données est un problème, j'y réfléchirais à deux fois avant d'utiliser Elasticsearch comme seul mécanisme de stockage de vos données. Il peut y arriver à un moment donné, mais je ne suis pas sûr qu'il y soit encore.

En termes de vitesse, non seulement Elastic / Lucene est à égalité avec la vitesse de requête de Mongo, dans votre cas où il y a "très peu de constante en termes de champs utilisés pour le filtrage à tout moment", mais il pourrait s'agir de commandes de magnitude plus rapide, d'autant plus que les ensembles de données deviennent plus grands. La différence réside dans les implémentations de requêtes sous-jacentes:

  • Elastic / Lucene utilise le modèle d'espace vectoriel et des index inversés pour la recherche d'informations , qui sont des moyens très efficaces de comparer la similitude des enregistrements avec une requête. Lorsque vous interrogez Elastic / Lucene, il connaît déjà la réponse; la majeure partie de son travail consiste à classer les résultats pour vous par les plus susceptibles de correspondre aux termes de votre requête. C'est un point important: les moteurs de recherche, contrairement aux bases de données, ne peuvent pas vous garantir des résultats exacts; ils classent les résultats en fonction de leur proximité avec votre requête. Il se trouve que la plupart du temps, les résultats sont presque exacts.
  • L'approche de Mongo est celle d'un magasin de données à usage plus général; il compare les documents JSON les uns aux autres. Vous pouvez en tirer d'excellentes performances par tous les moyens, mais vous devez soigneusement concevoir vos index pour qu'ils correspondent aux requêtes que vous exécuterez. Plus précisément, si vous avez plusieurs champs par lesquels vous allez interroger, vous devez soigneusement élaborer vos clés composéesafin qu'ils réduisent le jeu de données qui sera interrogé le plus rapidement possible. Par exemple, votre première clé doit filtrer la majorité de votre ensemble de données, la seconde doit filtrer davantage ce qui reste, et ainsi de suite. Si vos requêtes ne correspondent pas aux clés et à l'ordre de ces clés dans les index définis, vos performances chuteront un peu. D'un autre côté, Mongo est une véritable base de données, donc si la précision est ce dont vous avez besoin, les réponses qu'elle donnera seront parfaites.

Pour les anciens enregistrements expirant, Elastic dispose d'une fonction TTL intégrée. Mongo vient de l'introduire à partir de la version 2.2 je pense.

Étant donné que je ne connais pas vos autres exigences telles que la taille prévue des données, les transactions, la précision ou l'apparence de vos filtres, il est difficile de faire des recommandations spécifiques. J'espère qu'il y en a assez ici pour vous aider à démarrer.

gstathis
la source
92
Juste pour commenter que c'est probablement le plus haut niveau de réponse à espérer sur un sujet d'architecture sur ce site. Merci d'être érudit, analytique, articulé et vraiment engagé dans le scénario.
matanster
12
En ce qui concerne la précision, vous pourrez peut-être la contrôler avec Elastic / Lucene en choisissant la façon dont vous tokenisez et analysez vos champs. Si vos champs ne sont pas analysés (c.-à-d. Divisés en termes séparés par des espaces), vous pouvez forcer le moteur de recherche à les traiter tels quels. Ensuite, si vous effectuez une requête à l'aide d'une requête de termes ( elasticsearch.org/guide/reference/query-dsl/term-query.html ), vous pouvez vous assurer que vous n'obtenez que des résultats de correspondance exacts. Cette approche serait similaire à la façon dont un DB régulier ferait une correspondance exacte.
gstathis
7
MISE À JOUR - Pour ceux qui sont curieux de savoir si cette réponse est toujours pertinente, MongoDB dispose désormais d'index de texte intégral pour fournir les mêmes fonctionnalités et avantages que la recherche élastique a été décrite dans la réponse sélectionnée. Ils sont stockés sous forme d'index séparés et peuvent être interrogés selon les besoins, mais vous ne perdez aucun des avantages d'avoir une base de données à usage général. J'utilise MongoDB à des fins générales et pour les requêtes de recherche de texte depuis l'année dernière et je le recommande vivement. Juste mes deux cents.
Jason Roell
@JasonRoell J'ai besoin d'entendre cela de quelqu'un, tous les autres articles sur Internet ont été écrits avant la publication des index de texte, alors que l'expression régulière lente était la seule option. j'aimerais voir une comparaison de vitesse entre mongodb et
elasticsearch