# How to check OR operator between two or more relationships

**URL:** <https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094>\
**Category:** General\
**Tags:** cypher\
**Created:** [March 21, 2020, 10:43am UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094 "2020-03-21T10:43:21Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 21, 2020, 10:43am UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/1 "2020-03-21T10:43:21Z")

</div>

hi  
i want to check existence of a node with some relationships that if one of them exist the node must be selected as result.

:X means anythings  
match (a:A)-[:X]-\>(b:B)-[:X]-\>(c:C),  
(b)-[:X]-\>(d:D),  
(b)-[:X]-\>(e:E)  
return a,b

this means select all of (a:A)-[:X]-(b:B) (s) that b has at least one c AND one d AND one e  
how can i change this behavior into :  
Select all of (a:A)-[:X]-(b:B) which b has  
1- one c:C  
OR  
2- one d:D  
OR  
3- one e:E

thanks a lot

---

<div class="post-metadata">

**Author:** ![jaini.kiran](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/jaini.kiran/32/9706_2.png) [@jaini.kiran](https://community.neo4j.com/u/jaini.kiran)\
**Post date:** [March 21, 2020, 3:41pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/2 "2020-03-21T15:41:43Z")

</div>

```auto
MATCH (a:A)-[:X]-(b:B)
OPTIONAL MATCH (b:B)-[:X]->(c:C), (b)-[:X]->(d:D), (b)-[:X]->(e:E)
RETURN c, d, e

```

Check out this link: [OPTIONAL MATCH - Cypher Manual](https://neo4j.com/docs/cypher-manual/current/clauses/optional-match/)  
Hope this helps you.

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 21, 2020, 5:01pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/3 "2020-03-21T17:01:41Z")

</div>

hi,  
I guess i didn't explain my question well.  
I want to select those nodes (in this example B) that at least has one of (C) OR (B) OR (D) ,not those (B)s that hasn't any of them.  
optional match tell to me :  
you can select all of (B) regardless of related Node after that in cypher in this situation (C), (D), (E)  
this means i can select  
those (B)s that has no (C) or (D) or (E)  
those (B)s that has only (C)  
those (B)s that has only (D)  
those (B)s that has only (E)  
those (B)s that has (C) and (D)  
those (B)s that has (C) and (E)  
those (B)s that has (D) and (E)  
and those (B)s that has (C) and (D) and (E)  
i find one solution for this but that is verbose.  
//step 1 : create list of (B)s that has (C) named as list1  
MATCH (a:A)-[:X]-\>(b:B)-[:X]-\>(c:C)  
with collect(b) as list1  
//step2: create list of (B)s that has (D) named as list2  
MATCH (a:A)-[:X]-\>(b:B)-[:X]-\>(d:D)  
with list1, collect(b) as list2  
//step 3: create list of (B)s that has (E) named as list3  
MATCH (a:A)-[:X]-\>(b:B)-[:X]-\>(d:D)  
with list1, list2, collect(b) as list3  
//step 4 : match those (B)s that exist at least in one of list1 or list2 or list3  
MATCH (a:A)-[:X]-\>(b:B)  
where any( item in list1 where item=b) or any( item in list2 where item=b) or any(item in list3 where item=b)  
return a,b  
i know this is correct, but i don't know this is efficient  
thanks to any one that help.

---

<div class="post-metadata">

**Author:** ![intouch\_vivek](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/intouch_vivek/32/4097_2.png) [@intouch\_vivek](https://community.neo4j.com/u/intouch_vivek)\
**Post date:** [March 21, 2020, 5:31pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/4 "2020-03-21T17:31:04Z")

</div>

@bozorgi

Welcome to the group.  
You can try this  
match (a:A)-[:X]-\>(b:B)-[:X]-\>(c:C)  
return a,b  
Union  
match (a:A)-[:X]-\>(b:B)-[:X]-\>(d:D)  
return a,b  
Union  
match (a:A)-[:X]-\>(b:B)-[:X]-\>(e:E)  
return a,b

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 21, 2020, 5:55pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/5 "2020-03-21T17:55:20Z")

</div>

Thank Vivek for your reply  
This is correct.  
But if I want to do it without any Union how can I do it.  
suppose this pattern  
(A)--\>(B)--\>(C)  
(C)--\>(M)  
(C)--\>(N)  
(B)--\>(D)  
(B)--\>(E)--\>(F)  
(E)--\>(G)  
In B, C and E ( branch points) between outgoing relationships OR operator exists.  
As a general approach how can do this in one cypher with one return statement.

---

<div class="post-metadata">

**Author:** ![jaini.kiran](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/jaini.kiran/32/9706_2.png) [@jaini.kiran](https://community.neo4j.com/u/jaini.kiran)\
**Post date:** [March 21, 2020, 6:25pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/6 "2020-03-21T18:25:16Z")

</div>

```auto
MATCH (a:A)-[:X]->(b:B), (c:C), (d:D), (e:E)
where ((b:B)-[:X]->(c:C) OR (b:B)-[:X]->(d:D) OR (b:B)-[:X]->(e:E))
RETURN a,b

```

---

<div class="post-metadata">

**Author:** ![intouch\_vivek](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/intouch_vivek/32/4097_2.png) [@intouch\_vivek](https://community.neo4j.com/u/intouch_vivek)\
**Post date:** [March 21, 2020, 6:39pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/7 "2020-03-21T18:39:06Z")

</div>

Not sure if I completely understood your requirement.  
However to generalize A-\>B-\>\* try below  
Match path= (a:A)-[_]-\>(b:B)-[_]-\> ()  
return path

If you want to specify the relationship name then better

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 21, 2020, 7:22pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/8 "2020-03-21T19:22:42Z")

</div>

Thank jaini. Kiran  
I have to test this. If this works, my problem will be solved.

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 22, 2020, 7:08am UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/9 "2020-03-22T07:08:48Z")

</div>

thanks for your reply

i am working on some patterns, some of them are as simple as linear pattern such as

- (A)-[R]-\>(B)-[R]-\>(C)  
some of them are a little more complicated
- (A)-[R]-\>(B)-[R]-\>(C)
- 

```
              (B)-[R]->(D)

```

in these cases one or more Branch Point exist in patterns. Nodes like B are Branch Point. which means in this point pattern forked into more than one line of pattern.  
(B) = branch point  
1- (B)-[R]-\>(C)  
2- (B)-[R]-\>(D)  
...  
these (BP)s may be chained together. Some of these (BP)s have special conditions, and some haven't.  
for example  
1- B must be related to C by R  
and  
2- B must be related to D by R

- as in Neo4j Cypher documents explained, these conditions must be written with WHERE clause after respective MATCH clause. so we have

- MATCH ((a:A)-[:R]-\>(b:B)),

- 

```
                            ((b)-[:R]->(:C)),

```

- 

```
                            ((b)-[:R]->(:D))

```

return a,b

- if operator of this (BP) changes to OR as [jaini.kiran] explained the cypher changes as follows

MATCH (a:A)-[:R]-\>(b:B)  
where (b)-[:R]-\>(:C) OR (b)-[:R]-\>(:D)  
return a,b  
or as you explained this case can be implemented with UNION clause

- if these (BP)s are repeated

- (A)-[R]-\>(B)

- 

```
          (B)-[R]->(C)

```

- 

```
                        (C)-[R]->(M)

```

- 

```
                        (C)-[R]->(N)

```

- 

```
         (B)-[R]->(D)

```

- 

```
                       (D)-[R]->(P)

```

- 

```
                       (D)-[R]->(Q)

```

cypher statement changes to :  
MATCH (a:A)-[R]-\>(b:B)  
WHERE exists((b)-[:R]-\>(:C) \*\*1) or exists((b)-[:R]-\>(:D) \*\*2)  
RETURN a,b

Suppose all (BP)s have OR operator between outgoing relationships.

Question : in \*\*1 and \*\*2 how can i write the continuation of the cypher.

i counted on the (BP)s and their leaves.  
(BP)s B,C and D  
Leaves M,N,P and Q  
based on leaves for each BP create a list of valid (BP)s. from last to first

\*\* C Break Point  
1-MATCH (A)-[R]-\>(B)-[R]-\>(C)-[R]-\>(M)  
with collect(C) as c\_list1  
2-MATCH (A)-[R]-\>(B)-[R]-\>(C)-[R]-\>(N)  
with c\_list1, collect(C) as c\_list2  
3-MATCH (A)-[R]-\>(B)-[R]-\>(c:C)  
where any(item in c\_list1 where item=c) or any(item in c\_list2 where item=c)  
with collect(c) as c\_list

\*\* D Break Point  
4-MATCH (A)-[R]-\>(B)-[R]-\>(D)-[R]-\>(P)  
with c\_list, collect(D) as d\_list1  
5-MATCH (A)-[R]-\>(B)-[R]-\>(D)-[R]-\>(Q)  
with c\_list, collect(D) as d\_list2  
6-MATCH (A)-[R]-\>(B)-[R]-\>(d:D)  
where any(item in d\_list1 where item=d) or any(item in d\_list2 where item=d)  
with c\_list, collect(d) as d\_list

\*\* B Break Point  
7-MATCH (A)-[R]-(B)-[R]-(c:C)  
where any( item in c\_list where item=c)  
with d\_list, collect(B) as b\_list1  
8-MATCH (A)-[R]-(B)-[R]-(d:D)  
where any( item in d\_list where item=d)  
with b\_list1, collect(B) as b\_list2

\*\* Create Result  
9-MATCH (a:A)-[R]-\>(b:B)  
where any(item in b\_list1 where item=b) or any(item in b\_list2 where item=b)  
return a,b

? is this the right solution

thanks a lot

---

<div class="post-metadata">

**Author:** ![intouch\_vivek](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/intouch_vivek/32/4097_2.png) [@intouch\_vivek](https://community.neo4j.com/u/intouch_vivek)\
**Post date:** [March 22, 2020, 10:15am UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/10 "2020-03-22T10:15:06Z")

</div>

@bozorgi,

If I see at high level you are trying to implement tree.  
If you provide small sample dataset and usecase then it will be useful for us to help you out.

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 22, 2020, 11:34am UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/11 "2020-03-22T11:34:29Z")

</div>

hi  
I am working on translating abstract queries into neo4j queries.  
The user defines an abstract query based on a set of predefined concepts.  
In this task, the major challenge is to manages points ( Query Node not Graph Node ) where different conditions defined on a node. these challenges are aggregate functions ( count, exists, not-exists ) and combining conditions with OR.  
I am currently working on solving these challenges so that an unlimited number of these points can be managed within one command ( cypher statement with only one RETURN clause )  
this is very similar to nested queries in relational databases. some inner queries provide source for outer queries - reverse approach.  
In the previous post I defined a pattern that results the tree without deducing the relationships outside the pattern. But if the inference settings are made, the result is graph.  
(A)-[R]-\>(B)  
-----------(B)-[R]-\>(C)  
-----------------------(C)-[R]-\>(M)  
-----------------------(C)-[R]-\>(N)  
-----------(B)-[R]-\>(D)  
-----------------------(D)-[R]-\>(P)  
-----------------------(D)-[R]-\>(Q)

Is the cypher in the previous post correct?  
I apologize in advance for my poor English.

---

<div class="post-metadata">

**Author:** ![intouch\_vivek](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/intouch_vivek/32/4097_2.png) [@intouch\_vivek](https://community.neo4j.com/u/intouch_vivek)\
**Post date:** [March 22, 2020, 2:51pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/12 "2020-03-22T14:51:20Z")

</div>

@bozorgi  
I clearly understood your project. You are trying to create a wrapper framework on Cypher that is rather user friendly so that one can query Neo4j DB using that wrapper rather than Cypher. The wrapper framework will call Cypher.  
To implement that framework your are trying to ingest cypher statements in tree and now you want to traverse the tree.  
You can try the solutions given in last post by me of @jaini.kiran.  
However I would say that if my understanding is correct, Nodes A,B,C,D,E,.. belong to one Label rather than they distinct Lables.  
Traversing the tree can we using with recursive loop please look into the solution provided by @ Andrew in [Determine number of node relationships in recursive query - #3 by r.chevalier335](https://community.neo4j.com/t/determine-number-of-node-relationships-in-recursive-query/16103/3)

---

<div class="post-metadata">

**Author:** ![bozorgi](https://sea1.discourse-cdn.com/flex021/user_avatar/community.neo4j.com/bozorgi/32/9995_2.png) [@bozorgi](https://community.neo4j.com/u/bozorgi)\
**Post date:** [March 22, 2020, 5:18pm UTC](https://community.neo4j.com/t/how-to-check-or-operator-between-two-or-more-relationships/16094/13 "2020-03-22T17:18:35Z")

</div>

Thank for your time.
