Search code examples
graphneo4jcyphergraph-databases

In Neo4j what's the best practice to store and match specific path if multiple pathes are exist (with different property)


I am a beginner in Neo4j and graph databases.

I want to store scene details. I have 3 actors. They are fighting in the scene. And I want to store who kicked whom in the specific scene. And not in another scene. I have these relationships:

(s1:Scene {id: 1})
(s2:Scene {id: 2})
(a1:Actor) - [:ACTING_IN] -> (s1:Scene {id: 1})
(a1:Actor) - [:ACTING_IN] -> (s2:Scene {id: 2})
(a2:Actor) - [:ACTING_IN] -> (s1:Scene {id: 1})
(a2:Actor) - [:ACTING_IN] -> (s2:Scene {id: 2})
(a3:Actor) - [:ACTING_IN] -> (s1:Scene {id: 1})
(a3:Actor) - [:ACTING_IN] -> (s2:Scene {id: 2})
(a1:Actor) - [:Kick  {scene: 1}] -> (a2:Actor)  
(a1:Actor) - [:Punch {scene: 1}] -> (a2:Actor)  
(a1:Actor) - [:Kick  {scene: 1}] -> (a3:Actor)  
(a1:Actor) - [:Kick  {scene: 2}] -> (a3:Actor)  

What's the best practice to store these if performance is crucial to query who kicked whom grouped by scenes?
The scene in the Kick relationship seems to be a Foreign key and I don't know if it is good or not.


Solution

  • After I read a lot of articles, I found that the solution is the hyperedges/intermediate nodes.

    One modelling technique that is useful in this model is the concept of a hyperedge. Hyperedges (or intermediate nodes) are often created to model relationships that exist between more than two entities. They are often created to represent the connection of multiple entities at a point in time.

    Link to documentation: Neo4j documentation

    So an example solution is like this:

    (s1:Scene {id: 1}) <- [:IN]   -  (ac1:Action {id: 1})
    (a1:Actor)          - [:KICK] -> (ac1:Action {id: 1})
    (a2:Actor)         <- [:KICK] -  (ac1:Action {id: 1})
    

    In a movie, there are a lot of scenes, actions and actors.
    An Action describes the relationship between two actors in a specific scene.