I am trying to write a cypher query to get a subgraph for a set of nodes by multiple relationship path. The subgraph I want to query looks like this.
Node1(Start node) is related to relatednodes, locations and actors. Actors are related to roles and movies.
The requirement is to fetch n nodes(which will be the start nodes of subgraph) with full subgraph. ( Given we know the relationship that we want to get in subgraph).
In my case get first 10 Node1 nodes and get the subgraph that is related by ACT_FOR, RELATED_TO, LOCATED_IN,HAS_ROLE, HAS_MOVIE
Query1 : Fetches nodes and subgraph as a flat list
Match(node:Node1
)
WITH node
SKIP 0 LIMIT 10
OPTIONAL Match(node)-[avf:ACT_FOR
]-(actor)
OPTIONAL Match(node)-[sa:RELATED_TO
]->(relatednode)
OPTIONAL Match(node)-[li:LOCATED_IN
]->(locatedin)
OPTIONAL MATCH(actor)-[db:HAS_ROLE
]-(role)
OPTIONAL Match(actor)-[dt:HAS_MOVIE
]->(movie)
RETURN node,actor,role,movie,relatednode,locatedin
Query 2: Fetches nodes and collect the result
Match(node:Node1
)
WITH node
SKIP 0 LIMIT 10
OPTIONAL Match(node)-[avf:ACT_FOR
]-(actor)
WITH node, actor
OPTIONAL Match(actor)-[db:HAS_ROLE
]-(role)
OPTIONAL Match(actor)-[dt:HAS_MOVIE
]->(movie) WITH node, actor, role, movie
With node, actor{.name
, roles : collect ( role) , movies : collect(movie)} as actors
WITH node, collect(actors) as _actors
OPTIONAL Match(node)-[sa:RELATED_TO
]->(relatednode)
With node, _actors , collect(relatednode) as _relatednodes
OPTIONAL Match(node)-[li:LOCATED_IN
]->(locatedin)
WITH node, _actors , _relatednodes, collect(locatedin) as _locatedin
RETURN node, _actors , _relatednodes, _locatedin
The first query gives result as a flat table. Second one will aggregate the result but the query is too complicated and difficult to generalize. (I want to write a generalized query to get the subgraph for given nodes). Is there any other way to get subgraph for a set of nodes by multiple relationship? I came across apoc.subGraph , but that only supports single/different relationship to one target node. I am attaching sample data set.
MERGE (node1:Node1 {name: "Node1"})
MERGE (actor1:ACTOR {name: "actor1"})
MERGE (actor2:ACTOR {name: "actor2"})
MERGE (role1:ROLE {name: "role1"})
MERGE (role2:ROLE {name: "role2"})
MERGE (role3:ROLE {name: "role3"})
MERGE (movie1:MOVIE {name: "movie1"})
MERGE (relatednode1:Node1 {name: "relatednode1"})
MERGE (relatednode2:Node1 {name: "relatednode2"})
MERGE (location1:LOCATION {name: "location1"})
MERGE (node2:Node1 {name: "Node2"})
MERGE (actor3:ACTOR {name: "actor3"})
MERGE (actor4:ACTOR {name: "actor4"})
MERGE (role4:ROLE {name: "role4"})
MERGE (role5:ROLE {name: "role5"})
MERGE (role6:ROLE {name: "role6"})
MERGE (movie2:MOVIE {name: "movie2"})
MERGE (relatednode3:Node1 {name: "relatednode3"})
MERGE (relatednode4:Node1 {name: "relatednode4"})
MERGE (location2:LOCATION {name: "location2"})
MERGE (node3:Node1 {name: "Node3"})
MERGE (actor5:ACTOR {name: "actor5"})
MERGE (relatednode5:Node1 {name: "relatednode5"})
MERGE (node1)<-[:ACT_FOR]-(actor1)
MERGE (node1)<-[:ACT_FOR]-(actor2)
MERGE (actor1)-[:HAS_ROLE]->(role1)
MERGE (actor1)-[:HAS_ROLE]->(role2)
MERGE (actor2)-[:HAS_ROLE]->(role3)
MERGE (actor1)-[:HAS_MOVIE]->(movie1)
MERGE (actor2)-[:HAS_MOVIE]->(movie1)
MERGE (node1)-[:RELATED_TO]->(relatednode1)
MERGE (node1)-[:RELATED_TO]->(relatednode2)
MERGE (node1)-[:LOCATED_IN]->(location1)
MERGE (node2)<-[:ACT_FOR]-(actor3)
MERGE (node2)<-[:ACT_FOR]-(actor4)
MERGE (actor3)-[:HAS_ROLE]->(role4)
MERGE (actor3)-[:HAS_ROLE]->(role5)
MERGE (actor4)-[:HAS_ROLE]->(role6)
MERGE (actor3)-[:HAS_MOVIE]->(movie2)
MERGE (actor4)-[:HAS_MOVIE]->(movie2)
MERGE (node2)-[:RELATED_TO]->(relatednode3)
MERGE (node2)-[:RELATED_TO]->(relatednode4)
MERGE (node2)-[:LOCATED_IN]->(location2)
MERGE (node3)<-[:ACT_FOR]-(actor5)
MERGE (node3)-[:RELATED_TO]->(relatednode5)