Jim Heising
Jim Heising

Reputation: 4338

Creating a relationship to a relationship in Neo4j

Is it possible to create a relationship to a relationship in Neo4j?

The use-case goes something like this:

The graph would preferably look something like this:

(:Question {name:"What movie?"})-[:Option]->(:Movie {name:"Movie1"})
                                     ^   
                                     |
                                  [:Vote]
                                     |
                                  (:User)

I realize that one way I could solve this is with the following:

(:Question)-[:Option]->(:Movie)<-[:Vote]-(:User)

But then if I decide to remove the Movie as an Option in the future, I don't get to take advantage of DETACH and will have to manage removing the Vote relationship myself. Not to mention, if the Movie belongs to multiple categories, I have to keep track of which Question->Movie relationship it belongs to (probably with some sort of ID). It just seems very messy...

Is is possible to create a relationship to a relationship? Or am I going to have to manually enforce referential integrity?

Upvotes: 7

Views: 1650

Answers (2)

zakmck
zakmck

Reputation: 3004

I'm investigating this. The only reasonable way I can find is to assign an identifier to the relationship (:HAS in your case) and then use it in the pointing relationship (:VOTE).

Neo4j has internal IDs for this (see the ID() function), but I usually prefer to try to assign a semantically meaningful ID (like a person's national insurance number, a page URL or, in case of relations, the hash code of its concatenated endpoint's identifers).

Upvotes: 0

Bruno Peres
Bruno Peres

Reputation: 16365

Is is possible to create a relationship to a relationship?

No. This is not possible. According the docs:

A relationship connects two nodes, and is guaranteed to have a valid source and target node.

That is: the start and end point of a relationship should be a node.

I believe you should do some changes in your data model. For example:

Maybe the Option can be a node and not a relationship. Make more sense, not? This way:

 (:Category)-[:HAS]->(:Option)    

Also, the Vote can be a node too, and not a relationship... This way, when the user makes (a relationship, ahn?) a vote, this vote node will reference the option and the category that it is relative to.

 (:Category)-[:HAS]->(:Option)
          \           /
  [:FOR_CATEGORY][:FOR_OPTION]
            \      /
             (:Vote)
                |
            [:MAKES] 
                |
             (:User)

If, for example, you need to delete a Option and consequently the :Votes related to it you can do something like:

MATCH (o:Option {id:10})<-[:FOR_OPTION]-(v:Vote)
DETACH DELETE o
DETACH DELETE v

Make any sense? Sorry for my ASCII art. :)

Upvotes: 3

Related Questions