Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Neo4j Cypher alternative paths

Tags:

neo4j

cypher

I'm using Cypher and I need to build a query like the one that follows

(A) ----e1----(B)
   \           |
     \         |
       e3      e2
         \     |
           \   |
             (C)

where A, B and C are nodes and e1,e2 and e3 relationships connecting respectively A and B, B and C and A and C.

What I'm interested in are nodes A and C. This pattern should match when e1,B and e2 exist (and respect some properties) or relationship e3 exists (and respects some properties) or both. My problem here is that I'm not able to convert this in Cypher language. In order to give a relationship an identifier, I need to specify it in the MATCH clause, like

MATCH (A)--[e1]--(B)--[e2]--(C), (A)--[e3]--(C)

but doing so I'm telling Neo4j I want both (e1 and e3) and e2 to exist, and that's not the case. But if I don't give those relationships some identifiers, I can't search for any of their properties.

How can I build this query?

Thanks.

like image 545
fgiacc Avatar asked Sep 28 '22 19:09

fgiacc


1 Answers

Here is a query that should return, in each row, one distinct A and a collection of all the distinct C nodes to which it is connected, in either (or both) of the ways you have stated.

I assume that A, B, and C are all node labels.

To cleanly show the approach, here is a simplified query that does not look at the property values

MATCH p=(a:A)-[e*1..2]-(c:C)
WITH p, a, c, RELATIONSHIPS(p) AS rels
WHERE LENGTH(rels) = 1 OR HEAD(TAIL(NODES(p))):B
RETURN a, COLLECT(DISTINCT c) AS cs

In order to perform the tests on the property values, you need to modify the two terms in the WHERE clause (on either side of the OR). I hope this is clear.

like image 58
cybersam Avatar answered Oct 18 '22 14:10

cybersam