How to Model Real-World Relationships in a Graph Database (like Neo4j)?

后端 未结 1 1407
自闭症患者
自闭症患者 2021-02-01 06:36

I have a general question about modeling in a graph database that I just can\'t seem to wrap my head around.

How do you model this type of relationship: \"Newton invente

1条回答
  •  粉色の甜心
    2021-02-01 07:00

    Some of these things, such as invention_date, can be stored as properties on the edges as in most graph databases edges can have properties in the same way that vertexes can have properties. For example you could do something like this (code follows TinkerPop's Blueprints):

    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);   
    

    Now, lets expand it a little bit and add in 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);
    

    Adding in the books:

    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");
    

    To find out all of the books that Newton wrote on things he discovered we can construct a graph traversal. We start with Newton, follow the out links from him to things he discovered, then traverse links in reverse to get books on that subject and again go reverse on a link to get the author. If the author is Newton then go back to the book and return the result. This query is written in Gremlin, a Groovy based domain specific language for graph traversals:

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

    Thus, I hope I've shown a little how a clever traversal can be used to avoid issues with creating intermediate nodes to represent edges. In a small database it won't matter much, but in a large database you're going to suffer large performance hits doing that.

    Yes, it is sad that you can't associate edges with other edges in a graph, but that's a limitation of the data structures of these databases. Sometimes it makes sense to make everything a node, for example, in Mediator/CVT a performance has a bit more concreteness too it. Individuals may wish address only Tom Cruise's performance in "The Last Samurai" in a review. However, for most graph databases I've found that application of some graph traversals can get me what I want out of the database.

    0 讨论(0)
提交回复
热议问题