0

I have two lists

['avia', 'paul', 'tom']

['james','bond']

I am tring to find the shortes path between

avia -> james
paul -> james
tom -> james
avia -> bond
paul -> bond
tom -> bond

i create the query with in two loops and query neo4j every time so multiple calls are being made to neo4j. is ther a way to creat this in one stored procedure and make only one call to neo4j. sample query is like below

match p = allShortestPaths((a{name:'avia'})-[*..2]-(b {name:'james'})) return p
Bruno Peres
  • 15,845
  • 5
  • 53
  • 89
user2478236
  • 691
  • 12
  • 32
  • I solved using the below query UNWIND ['avia', 'paul', 'tom'] AS person UNWIND ['james','bond'] AS person2 match p = allShortestPaths((a)-[*..2]-(b)) WHERE a.name = person and b.name = person2 unwind relationships(p) as rels return person,person2, collect(distinct type(rels)) – user2478236 Jul 03 '17 at 11:57

3 Answers3

3

You'll need to use the UNWIND function to unwind your initial collection, like below.

WITH 'james' AS start_point,  ['avia', 'paul', 'tom'] AS end_points
UNWIND end_points as e
match p = allShortestPaths((a)-[*..2]-(b)) 
WHERE a.name = start_point and b.name = e
return start_point, p
Dom Weldon
  • 1,728
  • 1
  • 12
  • 24
  • Thank you for the answer but the second array can also have multiple values, I will update the question for more clarity. – user2478236 Jul 03 '17 at 10:39
2

You can unwind the list of start nodes like this :

UNWIND ['avia','paul','tom'] AS person
MATCH p=allShortestPaths((a {name: person})-[*..2]-(b {name: "james"}))
RETURN person, collect(p)

this will return you 3 rows (assuming a path is found) being

person, collection of paths found

Moreover, please use labels!

Christophe Willemsen
  • 19,399
  • 2
  • 29
  • 36
0

Easiest way should be just to match both start and end nodes using index lookups (via property membership within your list parameters) for both, then running shortestPath. Something like this, but with parameterized inputs:

WITH ['avia', 'paul', 'tom'] as startNames, ['james','bond'] as endNames
MATCH (start:Person), (end:Person)
WHERE start.name in startNames and end.name in endNames
MATCH p=allShortestPaths((start)-[*..2]-(end))
RETURN p

You'll want to have an index on :Person(name) (or on whatever equivalent you're using) so these utilize index lookups

InverseFalcon
  • 29,576
  • 4
  • 38
  • 51