Shashika
Shashika

Reputation: 1636

Match as logical AND/OR in Neo4j cypher queries

I am new to Neo4j and I need to query a matching graph or any subgraph as follows:

Query Graph

So I tried with OPTIONAL MATCH but I realized it would not provide me the required results. This is the query I tried previously.

OPTIONAL MATCH (w:W)-[:WRITES]->(a1:A{name:"A1"})
WITH w,a1
OPTIONAL MATCH (w)-[:WRITES]->(a2:A{name:"A2"})
WITH w,a1,a2
OPTIONAL MATCH (w)-[:WRITES]->(a3:A{name:"A3"})
WITH w,a1,a2,a3
OPTIONAL MATCH (w)-[:WRITES]->(a4:A{name:"A4"})
RETURN w,a1,a2,a3,a4

Though it is an optional match, it is still a logical AND match with outer join (in the context of SQL)

In my case, I need both OR and AND results in each match which means it should match any subgraph of the above interpreted graph.

So, I need to fetch results something as follows.

MATCH (w:W)-[:WRITES]->(a1:A{name:"A1"})

OR/AND

MATCH (w)-[:WRITES]->(a2:A{name:"A2"})

OR/AND

MATCH (w)-[:WRITES]->(a3:A{name:"A3"})

OR/AND

MATCH (w)-[:WRITES]->(a4:A{name:"A4"})
RETURN w,a1,a2,a3,a4

Is there any possibility to achieve my requirement through Neo4j cypher queries?

My results set should be look like this.

W, A1, A2, A3, A4
{name:w1,....}, {name:A1,....}, {name:A2,....}, {name:A3,....}, {name:A4,....}
{name:w1,....}, null, {name:A2,....}, null, {name:A4,....}
{name:w1,....}, null, null, null, {name:A4,....}
{name:w1,....}, {name:A1,....}, {name:A2,....}, null, null
{name:w1,....}, {name:A1,....}, null, {name:A3,....}, {name:A4,....}

Upvotes: 2

Views: 1020

Answers (1)

InverseFalcon
InverseFalcon

Reputation: 30397

If you want any :W nodes that are connected with a :WRITES relationship to any of the given :A nodes, then this query should work:

MATCH (w:W)-[:WRITES]->(a:A)
WHERE a.name in ["A1", "A2", "A3", "A4"]
RETURN w, a

EDIT

Ah, okay, so if I'm reading your update correctly, you want any :W node connected to one of these :A nodes, but then you want to know which of those :A nodes that node is connected to, and you want each of those :A nodes to have its own variable (this is the requirement that makes it a little tricky).

You can use some variation of my above query to find the w node then use OPTIONAL MATCHES from w as in your original query to get the answer. Alternately, you can use something like the below query:

MATCH (a1:A{name:"A1"}), (a2:A{name:"A2"}), (a3:A{name:"A3"}), (a4:A{name:"A4"})
UNWIND [a1, a2, a3, a4] as a
MATCH (w:W)-[:WRITES]->(a)
WITH a1, a2, a3, a4, w, collect(a) as connectedNodes
WITH w, CASE WHEN a1 in connectedNodes THEN a1 ELSE null END as a1, 
        CASE WHEN a2 in connectedNodes THEN a2 ELSE null END as a2,
        CASE WHEN a3 in connectedNodes THEN a3 ELSE null END as a3,
        CASE WHEN a4 in connectedNodes THEN a4 ELSE null END as a4
RETURN w, a1, a2, a3, a4

Upvotes: 1

Related Questions