Shortest Path using Neo4j, with relationships of Start and End Node - neo4j

I'm fairly new to Neo4j. I'm trying to get the shortest path for default movie database.
However, along with it I also need the start and end node(of type Person) to display there first level relation to any other node and if any person node on the path have a relation to the start and end node via some other node. Its better to explain with below pictures.
Normal shortestpath will look, something like this.
MATCH (p1:Person { name: 'Kevin Bacon' }),(p2:Person { name: 'Meg Ryan' }),
p = shortestPath((p1)-[*..15]-(p2))
return p
However my desired output is this one.
I tried below cypher. However i cannot understand, how to do it. I'm getting below result, which is incorrect.
MATCH (p1:Person { name: 'Kevin Bacon' }),(p2:Person { name: 'Meg Ryan' }),
p = shortestPath((p1)-[*..15]-(p2))
MATCH (p1:Person)-[r]-(b) // here i need foreach node on path for type person, get there relationships? However can't do that
return p,p1,r,b
Appreciate any help. Thanks.

You can get all the movies in the start and end nodes of shortest path. Then add the movies with the path.
MATCH p = shortestPath((p1:Person { name: 'Kevin Bacon' })-[*..15]-(p2:Person { name: 'Meg Ryan' }))
WITH p1, p2, p
MATCH (p1)-[:ACTED_IN]->(m1)
MATCH (p2)-[:ACTED_IN]->(m2)
RETURN p, m1, m2

Thanks for the reply Jose. It's close. I don''t want to restrict the relation just to "ACTED_IN" with (Movie). I just did a small modification.
MATCH p = shortestPath((p1:Person { name: 'Kevin Bacon' })-[*..15]-
(p2:Person { name: 'Meg Ryan' }))
UNWIND nodes(p) as n
MATCH (n)-[*]->(q)
RETURN n, q
However, i don't need the nodes highlighted in the box as they are not related to Meg and Kevin. Not sure how to exclude them.

Related

count the number of nodes after shortest path neo4j

MATCH (FooB:Actor { name: 'Foob' }),(AnnaH:Actor { name: 'Anna Hathaway' }), p = shortestPath((Foob)-[act:ACTED_IN*]-(AnnaH))
RETURN p
So this returns a graph p that is the shortest path from actors Foob to Anna Hathaway. How do I now count all nodes in p with a label of "chocolate"?
This should do it
RETURN SIZE([n IN nodes(p) WHERE n:chocolate]) AS count
Use nodes function in conjunction with UNWIND:
MATCH (FooB:Actor { name: 'Foob' }),(AnnaH:Actor { name: 'Anna Hathaway' }), p = shortestPath((Foob)-[act:ACTED_IN*]-(AnnaH))
UNWIND nodes(p) AS n
WITH n AS n
WHERE n.chocolate
RETURN COUNT(*)

Returning a new graph with Cypher or OpenCypher

This question comes from experience with the CONSTRUCT operator in SPARQL, which allows to take variable bindings in a graph query and return a new graph as result.
Is there anything like that in Cypher/OpenCypher?
I mean, suppose you have:
react1 - [part-of] -> pathway1
mol1 - [consumed-by] -> react1
mol2 - [consumed-by] -> react1
mol3 - [produced-by] -> react1
I'd like to return a simplified graph like:
pathway1 - [input] - mol1
pathway1 - [input] - mol2
pathway1 - [output] - mol3
Note that I've already played with WITH/COLLECT/UNWIND to return JSON structures very similar to the graph above, but this approach is much more difficult to write.
You can experiment with virtual relationships using the APOC library.
For example, you have the following test data:
MERGE p1 = (R:react {name:'react_1'})-[:`part-of`] ->(:pathway {name: 'pathway_1'})
MERGE p2 = (:mol {name: 'mol_1'})-[:`consumed-by`]->(R)
MERGE p3 = (:mol {name: 'mol_2'})-[:`consumed-by`]->(R)
MERGE p4 = (:mol {name: 'mol_3'})-[:`produced-by`]->(R)
RETURN *
Then you can try the following query:
MATCH (R:react)
MATCH (R)-[rp:`part-of`]-(p:pathway)
MATCH (m:mol)-[mr]-(R)
WITH p, m, mr,
CASE WHEN type(mr) = 'consumed-by'
THEN {from: p, type: "input", props: properties(mr), to: m}
WHEN type(mr) = 'produced-by'
THEN {from: m, type: "output", props: properties(mr), to: p}
END AS vRel
WITH vRel WHERE vRel IS NOT NULL
CALL apoc.create.vRelationship(
vRel.from,
vRel.type,
vRel.props,
vRel.to
) YIELD rel
RETURN vRel.from, rel, vRel.to
What will give the following result:

To get all nodes and path from edge to root using neo4j

I want to get all nodes information with paths from edge to root node.Using one of the edge property.
This is the three layer node structure.
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[p:Parent*0..]-(c:Child) RETURN c,g,p
This will return only B,C nodes with relationship like this
cypher used
CREATE (p: Parent{name : '1'} ) RETURN p
MATCH (p:Parent) WHERE p.name = '1' CREATE (c: Child{name : '2'} )<-[:parentToChild]-(p) RETURN p
MATCH (c:Child) WHERE c.name = '3' CREATE (g: GrandChild {name : '2'} )<-[:childToGrandChild]-(c) RETURN c
Please help..
You have missed parentTochild relationship which will be like,
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)<-[parentToChild*0..]-(p:Parent)
RETURN c,g,p
Try this :
MATCH (g:GrandChild{name:"C"})<-[:childToGrandChild]-(c:Child)
MATCH (c)<-[p:Parent*0..]-(c2:Child)
RETURN c,c2,g,p

match property on nodes in path of cypher shortestPath

For simplicity sake, let's say I have a graph like this (using actors/movies as an example):
Nodes:
Actor(id:1)
Actor(id:2)
Actor(id:3)
Movie(id:4,rating:'PG-13')
Movie(id:5,rating:'PG-13')
Relationships:
Actor(id:1) APPEARS_IN Movie(id:4)
Actor(id:2) APPEARS_IN Movie(id:4)
Actor(id:2) APPEARS_IN Movie(id:5)
Actor(id:3) APPEARS_IN Movie(id:5)
Cypher to create the sample graph:
create (a1:Actor {id: 1, name: 'Actor 1'})
create (a2:Actor {id: 2, name: 'Actor 2'})
create (a3:Actor {id: 3, name: 'Actor 3'})
create (m1:Movie {id: 4, rating:'PG-13', name: 'Movie 1' } )
create (m2:Movie {id: 5, rating:'PG-13', name: 'Movie 2' } )
create (a1)-[:APPEARS_IN]->(m1)
create (a2)-[:APPEARS_IN]->(m1)
create (a2)-[:APPEARS_IN]->(m2)
create (a3)-[:APPEARS_IN]->(m2)
return *
So now we have want to find the shortest path between Actor(id:1) and Actor(id:3). That's easy enough, we might try a cypher query like:
MATCH p=shortestPath((a:Actor { id: 1 })-[:APPEARS_IN*0..14]-(b:Actor { id: 3 })) RETURN NODES(p)
And we would get a result.
This is where my question comes in How can I put a requirement on the nodes in between (specifically the movie nodes) to only include rating:'R' as part of its path?
This query will only return the nodes of the shortest path between the two actors where all of the movies are R rated.
It filters out the Movie nodes and then checks to make sure that the rating of each movie node in the collection is R.
MATCH p=shortestPath((a:Actor { id: 1 })-[:APPEARS_IN*0..14]-(b:Actor { id: 3 }))
WHERE all ( movie in filter( m in nodes(p) where 'Movie' in labels(m)) where movie.rating = 'R')
RETURN nodes(p)

Shortest path through a node

How to get the shtortest path between two nodes, where the path is going through a specific node. This is what I've got so far:
MATCH (a:User { username:"User1" }),(b:User { username:"User2" }),(c:User { username:"User3" }),
p = allShortestPaths((a)-[*]-(b))
RETURN p
I want a result in which the path goes through User3 (c).
You can find each leg separately:
MATCH (a:User {username:"User1"}),(b:User {username:"User2"}),(c:User {username:"User3"}),
p = allShortestPaths((a)-[*]-(c)), q = allShortestPaths((c)-[*]-(b))
RETURN p, q
Be aware, though, that if you have very long paths, or cycles, this query can take a long time or never finish. You should consider putting an upper bound on the path lengths, e.g.:
MATCH (a:User {username:"User1"}),(b:User {username:"User2"}),(c:User {username:"User3"}),
p = allShortestPaths((a)-[*..10]-(c)), q = allShortestPaths((c)-[*..10]-(b))
RETURN p, q

Resources