Modeling Many to Many Relation

How can i model the following data :

  • "Person A" was hired by "Studio 1" to act in "Movie A"
  • "Person A" was hired by "Studio 1" to act in "Movie B"
  • "Person A" was hired by "Studio 1" to act in "Movie C"
  • "Person A" was hired by "Studio 2" to act in "Movie X"
  • "Person A" was hired by "Studio 2" to act in "Movie Y"
  • "Person A" was hired by "Studio 2" to act in "Movie Z"

and then answer the question : "Person A" was hired by "Studio 1" to act in which Movies ? or find the Movies that "Person A" acted in and that was hired by "Studio 1" ?

i have used following :

1. CREATE (s1:Studio {name: 'Studio A'}),(s2:Studio {name: 'Studio B'})
2. CREATE (p:Actor {name: 'Person A'})
3. CREATE (m1:Movie {name:'Movie A'}),(m2:Movie {name:'Movie B'}),(m3:Movie {name:'Movie C'})
4. CREATE (m4:Movie {name:'Movie X'}),(m5:Movie {name:'Movie Y'}),(m6:Movie {name:'Movie Z'})
1. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio A'}),(M:Movie {name: 'Movie A'})
 MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)
2. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio A'}),(M:Movie {name: 'Movie B'}) 
MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)
3. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio A'}),(M:Movie {name: 'Movie C'}) 
MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)
1. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio B'}),(M:Movie {name: 'Movie X'})
 MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)
2. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio B'}),(M:Movie {name: 'Movie Y'}) 
MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)
3. MATCH (A:Actor {name: 'Person A'}),(S:Studio {name: 'Studio B'}),(M:Movie {name: 'Movie Z'}) 
MERGE (S)-[:HIRE]->(A)-[:ACT]->(M)

But i can not seem to be able find all the movies that "Person A" acted in and that was hired by "Studio A"

I think an issue with your model is that there is no direct relationship between the studio and the movie. They are only connected through an Actor. This doesn't allow you to answer questions about a movie made by a studio.

Maybe a different data model would help. How about relating actors, movies, and studios with the following pattern:

(A)-[:ACT]->(M)-[:PRODUCED_BY]->(S)

This gives you a direct link between actors and movies, as well as movies and studios to answer your question. It is implied that an actor who acts in a movie produced by a studio, must have been hired by that studio in order to have acted in the movie.

You can then answer your question with the following query:

match (A:Actor{name: 'Person A'})-[:ACT]->(M:Movie)-[:PRODUCED_BY]->(S:Studio{name:'Studio A'})
return A as actor, S as studio, collect(M) as movies

The alternate graph would look like:

and the result:

You can then ask which studios hired Person A:

MATCH (A:Actor {name: 'Person A'})
MATCH (A)-[:ACT]->(M)-[:PRODUCED_BY]->(S)
RETURN A as actor, collect(distinct S) as studios

@glilienfield thanks to your reply, your model can only work, if the movie has only one relation PRODUCED_BY with a Sudio, if "Movie A" can be produced by Multiple Studios than the result will connect Person A to all the Studios.
I think my only solution, is to create a Person Node and an Actor Node, where the Actor Node will only have 3 unique relations, (Person)-[:PLAYED]->(Actor)-[:PART_OF] ->(Movie) and (Actor)-[:HIRED_BY]->(Studio)

i think my problem/solution is described here : Modeling Designs - Developer Guides

I see what you mean. Aligned with that article, how about a 'Contract' entity that has an actor, movie, and studio associated with it? I think this also aligns to your suggestion, but I am calling it Contract instead of Actor.

1 Like

@glilienfield thanks, yes i think a 'Contract' entity would solve my issue, best regards