3
votes

I have a schema, where nodes are connected by 2 types of relationship - r:A and r:B. I'm trying to write a pattern, which will find every path from node N to node M. This can be simply done by following cypher query:

match path = (n)-[:A|:B*]->(m) return path;

Unfortunately this is not what I need exactly. I need to find every path from (n) to (m) where depth via relation r:A can be infinite, but along the way only limited number of r:B relations can be use. In happy day scenario the cypher query would look like this:

match path = (n)-[:A*|:B*0..3]->(m) return path;

However cypher does not allow this syntax. I can't solve this problem even with usage of another "helping" node on the way:

match path = (n)-[:A*]->()-[:B*0..3]->(m) return path;

This does not match my need also, because the nodes can be interconnected in any possible way. For example:

(n)-[r:A]-()-[r:A]-()-[r:A]-(m)
(n)-[r:A]-(m)
(n)-[r:A]-()-[r:B]-()-[r:A]-()-[r:B]-()-[r:A]-()-[r:A]-(m)

Is there a way how this can be achieved? If not in cypher, can it be done in gremlin / neo4j traversal api / embedded functions of spring data neo4j project?

Thank's for the answers.

1

1 Answers

1
votes

Try this:

MATCH path = (n)-[:A|:B*]->(m)
WITH path, relationships(path) AS r, filter(rel in relationships(path)
WHERE type(rel) = 'B') AS Brels
WITH path, reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount <= 3
RETURN path

I don't know if I understand the question completely clear. Just let me know.

EDIT:
I added the second query after comments. This solution is ugly but it is good workaround.

MATCH path = (n)-[:A|:B*]-(m)
WITH path, filter(rel in relationships(path) WHERE type(rel) = 'B') AS Brels
WITH path, reduce(Bcount = 0, rel IN Brels | Bcount + 1) AS Bcount
WHERE Bcount <= 3
WITH path, relationships(path) AS rels
WITH path, rels, reduce(count = 0, rel IN rels | count + 1) AS count
WITH path, rels, range(0,count-1) as counter
WITH path, reduce(x = 0, c IN counter |
CASE WHEN (type(rels[c])='B' AND type(rels[c+1])='B') THEN x+200000 ELSE x+1 END) AS countX
WHERE countX<200000
RETURN path, countX