Head's Up! These forums are read-only. All users and content have migrated. Please join us at community.neo4j.com.
08-30-2020 11:37 PM
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.
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)
08-31-2020 08:06 AM
There appear to be several different questions here, you mention subgraph several times, and that is the visual, so I'll start there.
A simplified cypher to match the first 10 ('Node1' labeled nodes) and the nodes they are connected to (with just the relationships in your list). Note: the variable p contains paths
match (node:Node1) with node limit 10
match p=(node)-[:ACT_FOR|RELATED_TO|LOCATED_IN|HAS_ROLE|HAS_MOVIE*..1]-(n2)
RETURN p
match (node:Node1) with node limit 10
match p=(node)-[:ACT_FOR|RELATED_TO|LOCATED_IN|HAS_ROLE|HAS_MOVIE*..2]-(n2)
RETURN p
which returns this
There are additional ways to do it, but this option seems easier to read and understand.
08-31-2020 09:22 AM
But the result of the query you provided is a flat lists of nodes. I want to get the nodes and the relationship paths so that I can construct the graph(in the UI). Consider that there is an API which accepts type of node and relationships. Based on API input cypher query need to be executed and return an API response that will be used to create the subgraph in UI ( which will be similar to the visual I provided ).
08-31-2020 10:16 AM
Try this:
Start with your 'actor1' node and select maxLevel and in your case it should be 3. When you run this query this should show the graph you are looking for. Also, you can export the query results to a json file.
MATCH (c) WHERE c.name = "actor1"
CALL apoc.path.subgraphAll(c, {maxLevel: 3}) YIELD nodes, relationships
RETURN nodes, relationships
05-26-2022 08:09 AM
Hello, have you solved your problem? Your task is similar to my project, which aims at searching the similar subgraph from database with the cypher statement.
05-26-2022 09:29 AM
You can export the results json file and use that to create the subgraph.
MATCH (c) WHERE c.name = "actor1"
CALL apoc.path.subgraphAll(c, {maxLevel: 3}) YIELD nodes, relationships
RETURN nodes, relationships
WITH [ node in nodes | node {.*, label:labels(node)[0], id:tostring(id(node))}] as nodes, [rel in relationships
| rel {.*, fromNode:{label:labels(startNode(rel))[0], id:tostring(id(startNode(rel)))},type:type(rel), toNode:{label:labels(endNode(rel))[0], id:tostring(id(endNode(rel)))}}] as rels
WITH {nodes:nodes, relationships:rels} as json
RETURN apoc.convert.toJson(json)
05-26-2022 07:45 PM
Thanks! However, the subgraphall function can't specify the relationship types among nodes, because I want to search the subgraphs similar to the target subgraph from database. Do you have any idea about this topic? Thanks again.
05-26-2022 10:55 PM
I replied to your question on exporting the data. Please describe your problem so that I can help. Post your queries.
05-27-2022 05:19 AM
Hello, thanks for your reply!
(1)My target: To Search the isomophic subgraphs from the database with the cypher.
Inputing the cypher queries to return the nodes and relationships of all matched subgraphs.
(2)For example
The target subgraph is:
There are two types of nodes: road and junction and one type of relationship: LINK_WITH. The three road nodes are linked with each other, and they are all linked to the node junction.
Therefore, the cypher describes the nodes and relationships of the target subgraph, which restricts the types of nodes and the specified connected relationships (also specified nodes and relationship properties).
The cypher is:
match p1=(road1:Road)-[link1:LINK_WITH]-(road2:Road)-[link2:LINK_WITH]-(road3:Road),p2=(road1)-[link3:LINK_WITH]-(road3)
where 100<=link1.angle<=120 and 100<=link2.angle<=120 and 100<=link3.angle<=140
with road1, road2, road3, p1,p2
match p3=(road1)-[:LINK_WITH]-(jun:Junction)-[:LINK_WITH]-(road2)
with road1, road2, road3, jun,p1,p2,p3
match p4=(road2)-[:LINK_WITH]-(jun)-[:LINK_WITH]-(road3)
with road1,road2,road3, jun,p2,p1,p3,p4
match p5=(road3)-[:LINK_WITH]-(jun)-[:LINK_WITH]-(road1)
with road1,road2,road3, jun,p3,p1,p2,p4,p5
with collect(distinct road1) as cr1, collect(distinct road2) as cr2, collect(distinct road3) as cr3,collect(distinct jun) as cj, collect(distinct p1) as cp1,collect(distinct p2) as cp2,collect(distinct p3) as cp3,collect(distinct p4) as cp4,collect(distinct p5) as cp5
return cr1,cr2,cr3,cj,cp1,cp2,cp3,cp4,cp5
The matched subgraphs are:
(3)My problems:
First, I'm not sure whether the similar subgraphs within database are all matched .
Second, the cypher is complex, is there any concise and effective statement?
Third, the returned result is comolex, how to get nodes and relationships that can be phrased in .net driver simply.
Fourth, are there any tools that can match subgraphs directly and return the nodes and relationships. The apoc and gds library can't solve this problem, as far as I know, because they can't specify the relationships among specified nodes.
At last, thank you for sparing time reading my problems! I expect for your reply! Thanks again.
All the sessions of the conference are now available online