简体   繁体   中英

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:

  • I have a bunch of questions, like "What movie should we see?"
  • Each question can have many options like "Movie1", "Movie2", etc.
  • For each question I want a user to be able to vote for their favorite option.

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?

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 :Vote s 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. :)

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM