Graphdb/Neo4j relationship to another relationship, or relationship with 3 nodes

匿名 (未验证) 提交于 2019-12-03 01:39:01

问题:

I want to make IMDB's characters/roles structure in Neo4j. I'll need labels Person, Movie and Character. Character, because a character can be in multiple movies, played by different people.

Without Character, it's easy:

(Person)-[:PLAYS_IN]->(Movie)

But PLAYS_IN is a Character, so it would be something like:

(Person)-[:PLAYS_AS]->(Character)-[:PLAYS_IN]->(Movie)

but that doesn't work, because it doesn't have a direct Person-Movie relationship. Without that, everyone who ever played Peter Parker, is in every movie that has a Peter Parker.

There must be a Person-Movie relationship, but also a Person-Movie-Character relationship. How? This could work, but that's just nasty:

(Person)-[:PLAYS_IN {uuid}]->(Movie), (Character {uuid})

because now I'm creating my own foreign key kind of relationship. That's very ungraphdb. But it works:

MATCH (p:Person)-[r:PLAYS_IN]->(m:Movie), (c:Character) WHERE c.uuid = r.uuid RETURN p, c, m

by building a cartesian product =( which is very RDBMS, but not very graphdb. And I can't query Character-Movie or Character-Person, because that's not a real relationship.

How do I make a RDBMS link table with 3 foreign keys (movie_id, character_id, person_id) in Neo4j??

edit 1
The RDBMS equivalent:

movies (id, title)                         # e.g. Dragon Tattoo, or Spider's Web people (id, name)                          # e.g. Rooney Mara, or Claire Foy characters (id, name)                      # e.g. Lisbeth Salander roles (movie_id, person_id, character_id)  # 2 rows with 1 distinct character_id

回答1:

Your problem is solved by hypergraphs. But since neo4j does not support hypergraphs, you need to model them. For example:

CREATE (P1:Person {name: 'Tobey Maguire'}) CREATE (P2:Person {name: 'Nicholas Hammond'}) CREATE (CW1:CreativeWork {name: 'Spider-Man'}) CREATE (CW2:CreativeWork {name: 'The Amazing Spider-Man (TV Series)'}) CREATE (CH:Character {name: 'Spider-Man'})  CREATE (A1:Role) CREATE (A2:Role)  CREATE (P1)-[:PLAYS_AS]->(A1) CREATE (A1)-[:HAS_CHARACTER]->(CH) CREATE (A1)-[:PLAYS_IN]->(CW1)  CREATE (P2)-[:PLAYS_AS]->(A2) CREATE (A2)-[:HAS_CHARACTER]->(CH) CREATE (A2)-[:PLAYS_IN]->(CW2)



回答2:

Make your relationship between Actor and Movie a rich relationship, where an Actor who PLAYED_IN a Movie plays a specific Role. The Role is implemented as a separate entity (relationship entity) with its own properties and only becomes an entity when the relationship between Actor and Movie exists.

@NodeEntity public class Actor {     Long id;     @Relationship(type="PLAYED_IN") private Role playedIn; }  @RelationshipEntity(type = "PLAYED_IN") public class Role {     @Id @GeneratedValue   private Long relationshipId;     @Property  private String title;     @StartNode private Actor actor;     @EndNode   private Movie movie; }  @NodeEntity public class Movie {     private Long id;     private String title; }

(token from the mentioned link)



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!