0

Versions utilisées: Neo4j 3.0.6 avec le printemps-données-Neo4j 4.2.0.M1 pour la cartographie POJOmodélisation des données Neo4j: nœuds privés appartenant, les relations riches, serrures

Je suis en train de choisir la façon de modéliser les données avec neo4j et comparer les avantages/inconvénients des différentes solutions.

Exigences:

  • Un film a une liste dynamique des métadonnées (a métadonnées a 3 propriétés: 'clé', 'valeur', 'locale'). Le nombre de métadonnées d'un film n'est pas connu à l'avance, pas plus que les clés possibles. Ils doivent être séparables des autres propriétés techniques Movie car ils sont localisés et considérés comme des données métier. Les métadonnées sont la propriété du film et sont toujours accessibles depuis le film. Ils ne peuvent pas être partagées avec d'autres films
  • Les requêtes rapides chercher doit être possible sur les métadonnées des valeurs

exemple des métadonnées de film:

Movie metadata 
    locale 'en_GB': 
    title: 'Jurassic Park' 
    description: 'description in english' 
    locale 'fr_FR': 
    description: 'description en francais' 
    locale 'none': 
    actor: 'Jeff Goldblum' 

enter image description here Solution A

  • Un nœud par metadata (avec 3 propriétés par noeud: 'clé', 'valeur', 'locale')
  • Inconvénient: concept de privé appartenant à mettre en œuvre (suppression des nœuds orphelins de métadonnées à gérer manuellement, car non pris en charge par ressort données Neo4j/Neo4j-ogm)

Solution B

  • Un nœud unique par locale (avec une propriété: 'locale') (exemple: 'fr')
  • métadonnées comme relations riches (avec deux relations properti es: 'key', 'valeur')
  • Inconvénient: pour créer la relation, une serrure doit être prise sur le noeud Locale

Est-ce que quelqu'un a une expérience sur la solution B? À quel point faut-il verrouiller un nœud qui sera partagé par un million d'autres nœuds? Quel est l'impact de sur les performances et l'évolutivité?

Est-ce que quelqu'un a une meilleure solution de modélisation ?

+1

Il serait utile d'en savoir un peu plus sur les métadonnées. Chaque utilisateur a-t-il ses propres métadonnées sur un film ou n'est-il pas spécifique à l'utilisateur? Y a-t-il une raison pour laquelle vous ne pouvez pas stocker les métadonnées en tant que propriétés sur les noeuds de film? Certaines parties de métadonnées sont-elles censées agir comme des balises (ce qui signifie que vous pouvez interroger des métadonnées vers des films)? Ou allez-vous seulement accéder aux métadonnées d'un film plutôt que directement? – InverseFalcon

+0

Non, les métadonnées ne sont pas spécifiques à l'utilisateur. Mais ils sont localisés (je n'ai pas mentionné cela pour simplifier). Je pense que la seule façon de stocker des métadonnées sur les nœuds de films est à l'intérieur des tableaux, n'est-ce pas? Mais cela ne serait pas efficace pour récupérer des requêtes. Nous devons être en mesure de filtrer les films en fonction de leurs métadonnées. Et oui, nous accédons toujours aux métadonnées d'un film. – tigrou83

+0

Je ne suis pas exactement sûr de ce que vous voulez dire en ne pouvant stocker que des métadonnées dans des tableaux. Y at-il une raison pour laquelle vous ne pouvez pas simplement définir des propriétés sur vos noeuds de film? Vous pouvez toujours filtrer sur les propriétés de noeud dans vos clauses WHERE. Je suis toujours curieux de savoir quel type de métadonnées est censé être ... ce qui le différencie des propriétés du noeud que vous envisagiez d'utiliser? Pouvez-vous donner quelques exemples de ces métadonnées? – InverseFalcon

Répondre

3

tl, dr: aller à l'approche A. Ne vous embêtez pas avec orphelins :Locale nœuds sauf pour le nettoyage périodique, ils auront aucun effet sur les performances des requêtes.

Votre approche «A» est de loin la meilleure solution. Vous devez supprimer ces données du noeud :Movie, car vous avez raison, car il doit s'agir d'une carte imbriquée ou d'une liste de cartes, dont aucune n'est prise en charge par les propriétés de noeud. Pour le stockage, vous pouvez les convertir en une carte de listes, mais cela sera très difficile à interroger, et encore moins à interroger rapidement. Votre préoccupation concernant les nœuds "orphelins" est insignifiante; cela affectera les performances des requêtes et la taille des données de manière triviale, voire pas du tout, et est incroyablement facile à nettoyer périodiquement pour vous faciliter la tâche dans tous les cas.

MATCH (x:Locale) WHERE NOT (x) <- [:METADATA] -() DETACH DELETE x 

Est-ce qu'une fois par mois, ou même jamais, ce sera vraiment pas vous affecter beaucoup. Votre requête est déjà limitée par le reste du chemin, donc à moins que les nœuds orphelins ne soient plus nombreux que les nœuds attachés, vous n'ajoutez qu'un petit pourcentage à ce qui est probablement le plus grand jeu de votre requête, qui sera également supprimé par l'opération de requête sur le premier passage. En ce qui concerne le verrouillage, cela n'affectera que les requêtes d'écriture, et seulement lorsqu'une transaction d'écriture est ouverte. Vous pouvez exécuter un million de requêtes en lecture seule pendant que l'écriture est en cours et rien ne sera affecté. Malgré cela, le deuxième modèle est susceptible de ralentir les performances des requêtes, car comme mentionné ci-dessus, vous ne pouvez pas mettre d'index sur les propriétés de la relation.

1

Vous pouvez simplement stocker les « métadonnées » directement en tant que propriétés de chaque noeud Movie (sans avoir recours à key et value). C'est l'approche la plus simple, qui évite les problèmes de verrouillage et minimise le nombre de nœuds et de relations nécessaires. Vous pouvez à tout moment ajouter plus de propriétés à un nœud. Cette approche vous permet également d'ajouter des index pour des propriétés spécifiques à Movie auxquelles vous devez accéder rapidement lorsque vous lancez vos requêtes.

Par exemple:

CREATE (m:Movie {id: 123, title: 'Men in black', director: 'Barry Sonnenfeld'}); 

[UPDATE]

Si vous avez besoin de garder votre « métadonnées » proprement séparé de votre « données » et vous devez également être en mesure de localiser les métadonnées (y compris la spécification d'une propriété locale), vous pouvez associer chaque nœud Movie à un seul nœud Metadata pour chaque environnement local. Un nœud Metadatadirectement contient toutes les propriétés de métadonnées pour un environnement local unique pour un nœud Movie spécifique. Cypher peut être utilisé pour effectuer des "suppressions en cascade". Par exemple:

MATCH (m:Movie {id: 123}) 
OPTIONAL MATCH p=(m)-->() 
DELETE p; 
+0

C'est une approche simple, vous avez raison. Mais je dois distinguer les métadonnées des autres attributs car ce sont des informations commerciales séparées des autres attributs techniques. Et j'ai aussi oublié une partie importante (trop de simplification je suis désolé), les métadonnées ont aussi une propriété 'locale' (utilisée pour regrouper les métadonnées par langue). Je suis désolé, j'aurais dû le dire avant, ça change tout. Je vais mettre à jour le premier message avec ces détails. – tigrou83

+0

J'ai mis à jour ma réponse. – cybersam

+0

Oui exactement, donc cela ressemblera à la solution A (sauf que nous n'aurons pas un nœud par métadonnées). Cette solution fonctionne, cependant l'inconvénient est par exemple de gérer les suppressions en cascade manuellement (ce qui n'est pas supporté par spring-data-neo4j que j'utilise). J'espérais trouver une solution où je pourrais éviter cela. – tigrou83