Reputation: 49
I want to see if a path exists for a graph, given a list of sequential properties to search for. The list can be of variable length.
This is my most recent attempt:
WITH ['a', 'b', 'c', 'd'] AS search_list // can be any list of strings
// FOREACH (i IN range(search_list) |
// MATCH (a:Node {prop:i})-->(b:Node {prop:i+1}))
// RETURN true if all relationships exist, false if not
This solution doesn't work because you can't use MATCH
in a FOREACH
. What should I do instead?
Upvotes: 0
Views: 1341
Reputation: 29172
You can try to build a query manually for the match entire path and execute it using the function apoc.cypher.run
:
WITH ['a', 'b', 'c', 'd'] AS search_list
WITH search_list,
'MATCH path = ' +
REDUCE(c = '', i in range(0, size(search_list) - 2) |
c + '(:Node {prop: $props[' + i + ']})-->'
) +
'(:Node {prop: $props[' + (size(search_list) - 1) +']}) ' +
'RETURN count(path) as pathCount' AS cypherQuery
CALL apoc.cypher.run(cypherQuery, {props: search_list}) YIELD value
RETURN CASE WHEN value.pathCount > 0
THEN true
ELSE false
END AS pathExists
Upvotes: 2
Reputation: 66989
Assuming you pass the list of property values in a $props parameter and the length of that list is 4
, this query will first search for all paths of length 4 that have the desired start and end nodes (to narrow down the candidate paths), and then filter the interior nodes of the paths:
MATCH p=(a:Node {prop: $props[0]})-[*4]->(b:Node {prop: $props[-1]})
WITH p, NODES(p)[1..-2] AS midNodes
WHERE ALL(i IN RANGE(1, SIZE(midNodes)) WHERE midNodes[i-1] = $props[i])
RETURN p;
To increase efficiency, you should create an index on :Node(prop)
as well.
If this query returns nothing, then there are no matching paths.
Upvotes: 0