Comment modéliser les relations du monde réel dans une base de données graphique (comme Neo4j)?

j'ai une question générale au sujet de la modélisation dans une base de données de graphiques que je ne peux pas sembler enrouler ma tête autour.

comment modélisez-vous ce type de relation: "Newton a inventé le calcul"?

Dans un graphique simple, vous pourriez modèle comme ceci:

Newton (node) -> invented (relationship) -> Calculus (node)

... donc vous auriez un tas de relations graphiques" inventées " comme vous avez ajouté plus de gens et d'inventions.

Le problème est, vous commencez à avoir besoin d'ajouter un tas de propriétés à la relation:

  • invention_date
  • influential_concepts
  • influential_people
  • books_inventor_wrote

...et vous voudrez commencer à créer des relations entre ces propriétés et d'autres noeuds, tels que:

  • personnes influentes: relations avec les noeuds de personnes
  • books_inventor_wrote: relation de noeuds livre

alors maintenant il semble que le "dans le monde réel des relations" ("inventé") doit être en fait un nœud dans le graphe, et le graphique devrait ressembler à ceci:

Newton (node) -> (relationship) -> Invention of Calculus (node) -> (relationship) -> Calculus (node)

et pour compliquer encore plus les choses, d'autres personnes participent aussi à l'invention du calcul, donc le graphe devient maintenant quelque chose comme:

Newton (node) -> 
  (relationship) -> 
    Newton's Calculus Invention (node) -> 
      (relationship) -> 
        Invention of Calculus (node) -> 
          (relationship) -> 
            Calculus (node)
Leibniz (node) -> 
  (relationship) -> 
    Leibniz's Calculus Invention (node) -> 
      (relationship) -> 
        Invention of Calculus (node) -> 
          (relationship) -> 
            Calculus (node)

alors je pose la question parce qu'il semble que vous ne voulez pas définir de propriétés sur les objets réels de la base de données de graphe "relationship", parce que vous pourriez vouloir à un moment donné les traiter comme des nœuds dans le graphe.

Est-ce correct?

j'ai étudié l' Épurée Freebase Architecture, et ils semblent traiter tout comme un noeud. Par exemple, Freebase a l'idée d'un Mediator / CVT, où vous pouvez créer un noeud" Performance "qui relie un noeud" acteur "à un noeud" Film", comme ici:http://www.freebase.com/edit/topic/en/the_last_samurai. Pas tout à fait sûr si c'est la même question bien.

Quels sont les principes directeurs que vous utilisez pour déterminer si la "relation réelle" devrait en fait être un noeud graphique plutôt qu'une relation graphique?

Si il y a des bons livres sur ce sujet, j'aimerais savoir. Merci!

18
demandé sur Lance Pollard 2011-09-24 04:30:27

1 réponses

Certaines de ces choses, comme invention_date, peut être stocké sous forme de propriétés sur les bords comme dans la plupart des bases de données de graphes les bords peuvent avoir des propriétés de la même manière que les vertex peuvent avoir des propriétés. Par exemple, vous pouvez faire quelque chose comme ceci (le code suit les plans de TinkerPop):

Graph graph = new Neo4jGraph("/tmp/my_graph");
Vertex newton = graph.addVertex(null);
newton.setProperty("given_name", "Isaac");
newton.setProperty("surname", "Newton");
newton.setProperty("birth_year", 1643); // use Gregorian dates...
newton.setProperty("type", "PERSON");

Vertex calculus = graph.addVertex(null);
calculus.setProperty("type", "KNOWLEDGE");

Edge newton_calculus = graph.addEdge(null, newton, calculus, "DISCOVERED");
newton_calculus.setProperty("year", 1666);   

maintenant, développons-le un peu et ajoutons dans Liebniz:

Vertex liebniz = graph.addVertex(null);
liebniz.setProperty("given_name", "Gottfried");
liebniz.setProperty("surnam", "Liebniz");
liebniz.setProperty("birth_year", "1646");
liebniz.setProperty("type", "PERSON");

Edge liebniz_calculus = graph.addEdge(null, liebniz, calculus, "DISCOVERED");
liebniz_calculus.setProperty("year", 1674);

ajout dans les livres:

Vertex principia = graph.addVertex(null);
principia.setProperty("title", "Philosophiæ Naturalis Principia Mathematica");
principia.setProperty("year_first_published", 1687);
Edge newton_principia = graph.addEdge(null, newton, principia, "AUTHOR");
Edge principia_calculus = graph.addEdge(null, principia, calculus, "SUBJECT");

Pour trouver tous les livres que Newton a écrit sur ce qu'il a découvert, on peut construire un graphe transversal. Nous commençons avec Newton, suivez les liens out de lui à des choses qu'il a découvert, puis traversez les liens à l'envers pour obtenir des livres sur ce sujet et encore aller à l'envers sur un lien pour obtenir l'auteur. Si L'auteur est Newton alors revenir au livre et retourner le résultat. Cette requête est écrit dans Gremlin, Groovy spécifique au domaine de la langue graphique traversals:

newton.out("DISCOVERED").in("SUBJECT").as("book").in("AUTHOR").filter{it == newton}.back("book").title.unique()

ainsi, j'espère avoir montré un peu comment un clever traversal peut être utilisé pour éviter les problèmes avec la création de noeuds intermédiaires pour représenter les bords. Dans une petite base de données, cela n'aura pas beaucoup d'importance, mais dans une grande base de données, vous allez subir de grandes performances en faisant cela.

Oui, c'est triste de ne pas pouvoir associer les bords avec d'autres bords dans un graphique, mais c'est une limitation des structures de données de ces bases de données. Parfois, il est logique de faire de tout un noeud, par exemple, dans Mediator/CVT une performance a un peu plus de concret trop. Les individus peuvent souhaiter adresser seulement la performance de Tom Cruise dans "le dernier samouraï" dans un examen. Cependant, pour la plupart des bases de données de graphe j'ai trouvé que l'application de quelques traversées de graphe peut m'obtenir ce que je veux hors de la base de données.

18
répondu Pridkett 2012-07-05 13:54:00