paint-brush
Modélisation de données dans Elasticsearch : utilisation de requêtes imbriquées et de relations parent-enfantpar@rocksetcloud
7,992 lectures
7,992 lectures

Modélisation de données dans Elasticsearch : utilisation de requêtes imbriquées et de relations parent-enfant

par Rockset10m2024/04/17
Read on Terminal Reader

Trop long; Pour lire

La gestion des relations dans Elasticsearch peut être difficile, mais nous avons des requêtes imbriquées et des relations parent-enfant pour contourner ce problème, et bien plus encore.
featured image - Modélisation de données dans Elasticsearch : utilisation de requêtes imbriquées et de relations parent-enfant
Rockset HackerNoon profile picture
0-item
1-item



La modélisation des données dans Elasticsearch n'est pas aussi évidente que lorsqu'il s'agit de bases de données relationnelles. Contrairement aux bases de données relationnelles traditionnelles qui s'appuient sur la normalisation des données et les jointures SQL, Elasticsearch nécessite des approches alternatives pour gérer les relations.


Il existe quatre solutions courantes pour gérer les relations dans Elasticsearch :


  • Jointures côté application

  • Dénormalisation des données

  • Types de champs imbriqués et requêtes imbriquées

  • Relations parents-enfants


Dans ce blog, nous verrons comment concevoir votre modèle de données pour gérer les relations à l'aide du type de champ imbriqué et des relations parent-enfant. Nous aborderons l'architecture, les implications en termes de performances et les cas d'utilisation de ces deux techniques.

Types de champs imbriqués et requêtes imbriquées

Elasticsearch prend en charge les structures imbriquées, dans lesquelles les objets peuvent contenir d'autres objets. Les types de champs imbriqués sont des objets JSON dans le document principal, qui peuvent avoir leurs propres champs et types distincts. Ces objets imbriqués sont traités comme des documents distincts et masqués accessibles uniquement à l'aide d'une requête imbriquée.


Les types de champs imbriqués conviennent bien aux relations dans lesquelles l'intégrité des données, le couplage étroit et la structure hiérarchique sont importants. Il s'agit notamment des relations un-à-un et un-à-plusieurs dans lesquelles il existe une entité principale. Par exemple, représenter une personne et ses multiples adresses et numéros de téléphone dans un seul document.


Avec les types de champs imbriqués, Elasticsearch stocke l'intégralité du document, ainsi que les objets parents et imbriqués, sur un seul bloc et segment Lucene. Cela peut entraîner des vitesses de requête plus rapides puisque la relation est contenue dans un document.


Exemple de type de champ imbriqué et de requête imbriquée

Regardons un exemple d'article de blog avec des commentaires. Nous souhaitons imbriquer les commentaires sous l'article de blog afin qu'ils puissent être facilement interrogés ensemble dans le même document.


GITHUB JULIE-MILLS

 { "post_id": "1", "title": "Introduction to Elasticsearch Data Modeling", "content": "Exploring various data modeling options in Elasticsearch.", "comments": [ { "comment_id": "101", "text": "Great overview of data modeling!" }, { "comment_id": "102", "text": "Looking forward to more content." } ] }


Avantages des types de champs imbriqués et des requêtes imbriquées

Les avantages des relations d'objets imbriquées incluent :


  • Les données sont stockées dans le même bloc et segment Lucene : le stockage d'objets imbriqués dans le même bloc et segment Lucene entraîne des requêtes plus rapides car les données sont colocalisées.
  • Intégrité des données : étant donné que les relations sont conservées au sein du même document, cela peut garantir l'exactitude des requêtes imbriquées.
  • Modèle de données de document : facile pour les développeurs familiarisés avec le modèle de données NoSQL dans lequel vous interrogez des documents et des données imbriquées à l'intérieur de ceux-ci.

Inconvénients des types de champs imbriqués et des requêtes imbriquées

  • Inefficacité de la mise à jour : les mises à jour, les insertions et les suppressions sur n'importe quelle partie d'un document contenant des objets imbriqués nécessitent la réindexation de l'intégralité du document, ce qui peut être gourmand en mémoire, en particulier si les documents sont volumineux ou si les mises à jour sont fréquentes.


  • Performances des requêtes avec de grands champs imbriqués : si vous avez des documents avec des champs imbriqués particulièrement grands, cela peut avoir une implication en termes de performances. En effet, la demande de recherche récupère l'intégralité du document.


  • Plusieurs niveaux d'imbrication peuvent devenir complexes : L'exécution de requêtes sur des structures imbriquées comportant plusieurs niveaux peut encore devenir complexe. En effet, les requêtes peuvent impliquer des requêtes imbriquées dans des requêtes imbriquées, ce qui conduit à un code moins lisible.

Relations parents-enfants

Dans le mappage parent-enfant, les documents sont organisés en types parent et enfant. Chaque document enfant a une association directe avec un document parent. Cette relation est établie via une valeur de champ spécifique dans le document enfant qui correspond à l'ID du parent. Le modèle parent-enfant adopte une approche décentralisée dans laquelle les documents parent et enfant existent indépendamment.


Les jointures parent-enfant conviennent aux relations un-à-plusieurs ou plusieurs-à-plusieurs entre entités. Imaginez une application dans laquelle vous souhaitez créer des relations entre des entreprises et des contacts et rechercher des entreprises et des contacts ainsi que des contacts dans des entreprises spécifiques.


Elasticsearch rend les jointures parent-enfant performantes en gardant une trace des parents connectés à quels enfants et en faisant en sorte que les deux entités résident sur la même partition. En localisant l'opération de jointure, Elasticsearch évite le besoin d'une communication étendue entre les partitions, qui peut constituer un goulot d'étranglement en termes de performances.

Exemple de relations parent-enfant

Prenons l'exemple d'une relation parent-enfant pour les articles de blog et les commentaires. Chaque article de blog, c'est-à-dire le parent, peut avoir plusieurs commentaires, c'est-à-dire les enfants. Pour créer la relation parent-enfant, indexons les données comme suit :


 PUT my-index-000001 { "mappings": { "properties": { "post_id": { "type": "keyword" }, "post_id": { "type": "join", "relations": { "post": "comment" } } } } }


Un document parent serait un message qui ressemble à ceci :


 { "post_id": "1", "title": "Introduction to Elasticsearch Data Modeling", "content": "Exploring various data modeling options in Elasticsearch." }


Le document enfant serait alors un commentaire contenant le post_id le liant à son parent.


 { "comment_id": "101", "text": "Great overview of data modeling!", "post_id": "1" }


Avantages des relations parent-enfant

Les avantages de la modélisation parent-enfant comprennent :


  • Ressemble à un modèle de données relationnelles : dans les relations parent-enfant, les documents parent et enfant sont séparés et sont liés par un identifiant parent unique. Cette configuration est plus proche d'un modèle de base de données relationnelle et peut être plus intuitive pour ceux qui connaissent ces concepts.


  • Efficacité de la mise à jour : les documents enfants peuvent être ajoutés, modifiés ou supprimés sans affecter le document parent ou les autres documents enfants. Ceci est particulièrement utile lorsqu'il s'agit de traiter un grand nombre de documents enfants nécessitant des mises à jour fréquentes. Notez que l'association d'un document enfant à un parent différent est un processus plus complexe car le nouveau parent peut se trouver sur une autre partition.


  • Mieux adapté aux enfants hétérogènes : étant donné que les documents enfants sont stockés séparément, ils peuvent être plus efficaces en termes de mémoire et de stockage, en particulier dans les cas où il existe de nombreux documents enfants présentant des différences de taille significatives.

Inconvénients des relations parents-enfants

Les inconvénients des relations parent-enfant comprennent :


  • Requêtes coûteuses et lentes : la jonction de documents sur des index distincts ajoute du travail de calcul lors de l'exécution des requêtes, ce qui a également un impact sur les performances. Elasticsearch note que les requêtes parent-enfant peuvent être 5 à 10 fois plus lentes que l'interrogation d'objets imbriqués.


  • Surcharge de mappage : les relations parent-enfant peuvent consommer plus de ressources de mémoire et de cache. Elasticsearch gère une carte des relations parent-enfant, qui peut devenir volumineuse et consommer une mémoire importante, en particulier avec un volume élevé de documents.


  • Gestion de la taille des partitions : étant donné que les documents parents et enfants résident sur la même partition, il existe un risque potentiel de répartition inégale des données dans le cluster. Certaines partitions peuvent devenir beaucoup plus volumineuses que d'autres, en particulier s'il existe des documents parents contenant de nombreux enfants. Cela peut entraîner des défis dans la gestion et la mise à l'échelle du cluster Elasticsearch .


  • Réindexation et maintenance du cluster : Si vous devez réindexer des données ou modifier la stratégie de partitionnement , la relation parent-enfant peut compliquer ce processus. Vous devrez vous assurer que l’intégrité de la relation est maintenue lors de telles opérations. Les tâches de maintenance de routine du cluster, telles que le rééquilibrage des partitions ou les mises à niveau des nœuds, peuvent devenir plus complexes. Des précautions particulières doivent être prises pour garantir que les relations parents-enfants ne soient pas perturbées au cours de ces processus.


Elastic , la société derrière Elasticsearch, vous recommandera toujours d'effectuer des jointures côté application, une dénormalisation des données et/ou des objets imbriqués avant de s'engager dans la voie des relations parent-enfant.

Comparaison des fonctionnalités des requêtes imbriquées et des relations parent-enfant

Le tableau ci-dessous fournit un récapitulatif des caractéristiques des types de champs imbriqués et des requêtes ainsi que des relations parent-enfant pour comparer les approches de modélisation de données côte à côte.



Types de champs imbriqués et requêtes imbriquées

Relations parents-enfants

Définition

Imbrique un objet dans un autre objet

Relie les documents parents et enfants entre eux

Des relations

Un à un, un à plusieurs

Un à plusieurs, plusieurs à plusieurs

Vitesse des requêtes

Généralement plus rapide que les relations parent-enfant car les données sont stockées dans le même bloc et le même segment

Généralement 5 à 10 fois plus lent que les objets imbriqués, car les documents parents et enfants sont joints au moment de la requête.

Flexibilité des requêtes

Moins flexible que les requêtes parent-enfant car elle limite la portée de l'interrogation aux limites de chaque objet imbriqué

Offre plus de flexibilité dans les requêtes car les documents parents ou enfants peuvent être interrogés ensemble ou séparément

Mises à jour des données

La mise à jour des objets imbriqués a nécessité la réindexation de l'intégralité du document

La mise à jour des documents enfants est plus facile car elle ne nécessite pas la réindexation de tous les documents

Gestion

Une gestion plus simple puisque tout est contenu dans un seul document

Plus complexe à gérer en raison de l'indexation séparée et du maintien des relations entre les documents parents et enfants

Cas d'utilisation

Stockez et interrogez des données complexes avec plusieurs niveaux de hiérarchie

Relations dans lesquelles il y a peu de parents et beaucoup d'enfants, comme les produits et les critiques de produits


Alternatives à Elasticsearch pour la modélisation des relations

Bien qu'Elasticsearch propose plusieurs solutions de contournement aux jointures de style SQL , notamment les requêtes imbriquées et les relations parent-enfant, il est établi que ces modèles ne sont pas bien évolutifs. Lors de la conception d'applications à grande échelle, il peut être judicieux d'envisager une approche alternative avec des capacités de jointure SQL natives, Rockset .


Rockset est une base de données de recherche et d'analyse conçue pour la recherche SQL, les agrégations et les jointures sur toutes les données, y compris les données JSON profondément imbriquées. Au fur et à mesure que les données sont diffusées dans Rockset, elles sont codées dans les structures de données de base de la base de données utilisées pour stocker et indexer les données pour une récupération rapide. Rockset indexe les données de manière à permettre des requêtes rapides, y compris des jointures, à l'aide de son optimiseur de requêtes basé sur SQL. Par conséquent, aucune modélisation de données initiale n’est requise pour prendre en charge les jointures SQL.


L'un des défis d'Elasticsearch est de savoir comment préserver la relation de manière efficace lorsque les données sont mises à jour. L'une des raisons est qu'Elasticsearch repose sur Apache Lucene, qui stocke les données dans des segments immuables, ce qui nécessite une réindexation de tous les documents. Rockset utilise RocksDB, un magasin de valeurs-clés open source par Meta et conçu pour les mutations de données, pour pouvoir prendre en charge efficacement les mises à jour au niveau du champ sans avoir besoin de réindexer des documents entiers.

Comparaison d'Elasticsearch et Rockset à l'aide d'un exemple concret

Comparons l'approche de la relation parent-enfant dans Elasticsearch avec une requête SQL dans Rockset.


Dans l'exemple de relation parent-enfant ci-dessus, nous avons modélisé les publications avec plusieurs commentaires en créant deux types de documents :


  • publications ou le type de document parent

  • commentaires ou les types de documents enfants


Nous avons utilisé un identifiant unique, l'identifiant parent, pour établir la relation entre les documents parent et enfant. Au moment de la requête, nous utilisons Elasticsearch DSL pour récupérer les commentaires pour une publication spécifique.


Dans Rockset, les données contenant les publications seraient stockées dans une collection, une table dans le monde relationnel, tandis que les données contenant des commentaires seraient stockées dans une collection distincte. Au moment de la requête, nous réunirions les données à l’aide d’une requête SQL.


Voici les deux approches côte à côte :


Relations parent-enfant dans Elasticsearch


 POST /blog/posts/1 { "title": "Elasticsearch Modeling", "content": "A post about data modeling in Elasticsearch" } POST /blog/comments/2?parent=1 { "text": "Great post!" } POST /blog/comments/3?parent=1 { "text": "I learned a lot from this." }


Pour récupérer un article par son titre et tous ses commentaires, vous devrez créer une requête comme suit.


 GET /posts/_search { "query": { "bool": { "must": [ { "match": { "title": "Exploring Elasticsearch Models" } } ] } }, "inner_hits": { "_source": ["text"], "name": "comments", "path": "comments" } }


SQL dans Rockset

Pour ensuite interroger ces données, il vous suffit d’écrire une simple requête SQL.


 SELECT p.title, p.content, c.text FROM posts p JOIN comments c ON p.post_id = c.post_id WHERE p.post_id = 1;


Si vous disposez de plusieurs ensembles de données qui doivent être joints pour votre application, Rockset est plus simple et évolutif qu'Elasticsearch. Cela simplifie également les opérations puisque vous n'avez pas besoin de remodeler vos données, de gérer les mises à jour ou de réindexer les opérations.

Gestion des relations dans Elasticsearch

Ce blog a fourni une présentation des types de champs imbriqués et des requêtes imbriquées, ainsi que des relations parent-enfant dans Elasticsearch, dans le but de vous aider à déterminer la meilleure approche de modélisation des données pour votre charge de travail.


Les types de champs imbriqués et les requêtes sont utiles pour les relations un-à-un ou un-à-plusieurs où la relation est maintenue au sein d'un seul document. Ceci est considéré comme une approche plus simple et plus évolutive de la gestion des relations.


Le modèle de relation parent-enfant est mieux adapté aux relations un-à-plusieurs à plusieurs-à-plusieurs, mais il s'accompagne d'une complexité accrue, d'autant plus que les relations doivent être contenues dans une partition spécifique.


Si l’une des principales exigences de votre application est la modélisation des relations, il peut être judicieux d’envisager Rockset. Rockset simplifie la modélisation des données et propose une approche plus évolutive de la gestion des relations à l'aide des jointures SQL. Vous pouvez comparer les performances d'Elasticsearch et de Rockset en commençant dès aujourd'hui un essai gratuit avec 300 $ de crédits.