Overview
A composite query combines a list of linear queries with query conjunctions (UNION
, EXCEPT
, INTERSECT
, and OTHERWISE
).
<composite query statement> ::=
<linear query statement> <query conjunction> <linear query statement>
[ { <query conjunction> <linear query statement> }... ]
<query conjunction> ::=
"UNION" [ "DISTINCT" | "ALL" ]
| "EXCEPT" [ "DISTINCT" | "ALL" ]
| "INTERSECT" [ "DISTINCT" | "ALL" ]
| "OTHERWISE"
Details
- The query results produced by
<linear query statement>
s are combined. Therefore, the number, order and names of the return items must be identical in theRETURN
statements of all<linear query statement>
. - If the
DISTINCT
operator is specified, duplicate records across all return items are removed. IfALL
is specified, all records are retained regardless of repetition. When neitherDISTINCT
norALL
is explicitly stated,DISTINCT
is applied by default. - Different query conjunctions may be used within a composite query statement.
Example Graph

CREATE GRAPH myGraph {
NODE User ({name string}),
NODE Club (),
EDGE Follows ()-[{}]->(),
EDGE Joins ()-[{}]->()
} PARTITION BY HASH(Crc32) SHARDS [1]
INSERT (rowlock:User {_id:'U01', name:'rowlock'}),
(brainy:User {_id:'U02', name:'Brainy'}),
(purplechalk:User {_id:'U03', name:'purplechalk'}),
(mochaeach:User {_id:'U04', name:'mochaeach'}),
(lionbower:User {_id:'U05', name:'lionbower'}),
(c01:Club {_id:'C01'}),
(c02:Club {_id:'C02'}),
(rowlock)-[:Follows]->(brainy),
(brainy)-[:Follows]->(rowlock),
(mochaeach)-[:Follows]->(brainy),
(brainy)-[:Follows]->(purplechalk),
(purplechalk)-[:Follows]->(brainy),
(brainy)-[:Joins]->(c01),
(lionbower)-[:Joins]->(c01),
(mochaeach)-[:Joins]->(c02)
UNION
UNION
combines the results of two or more linear queries into a single result set that includes the distinct records present in any of the query.
MATCH (n:Club) RETURN n
UNION
MATCH (n) RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
C02 | Sys-gen | Club | |
C01 | Sys-gen | Club | |
U05 | Sys-gen | User | {name: "lionbower"} |
U04 | Sys-gen | User | {name: "mochaeach"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U02 | Sys-gen | User | {name: "Brainy"} |
U01 | Sys-gen | User | {name: "rowlock"} |
UNION ALL
UNION ALL
combines the results of two or more linear queries into a single result set that includes all records from each query without removing duplicates.
MATCH (n:Club) RETURN n
UNION ALL
MATCH (n) RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
C02 | Sys-gen | Club | |
C01 | Sys-gen | Club | |
U05 | Sys-gen | User | {name: "lionbower"} |
U04 | Sys-gen | User | {name: "mochaeach"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U02 | Sys-gen | User | {name: "Brainy"} |
U01 | Sys-gen | User | {name: "rowlock"} |
C02 | Sys-gen | Club | |
C01 | Sys-gen | Club |
EXCEPT
EXCEPT
returns a result set that includes distinct records from the first query that are not present in any of the subsequent queries.
MATCH ({_id: "U02"})-(n) RETURN n
EXCEPT
MATCH ({_id: "U05"})-(n) RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U04 | Sys-gen | User | {name: "mochaeach"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U01 | Sys-gen | User | {name: "rowlock"} |
EXCEPT ALL
EXCEPT ALL
returns a result set that includes records from the first query that are not present in any of the subsequent queries without removing duplicates.
MATCH ({_id: "U02"})-(n) RETURN n
EXCEPT ALL
MATCH ({_id: "U05"})-(n) RETURN n
Result: n
_id | _uuid | schema | values |
---|---|---|---|
U01 | Sys-gen | User | {name: "rowlock"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U04 | Sys-gen | User | {name: "mochaeach"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U01 | Sys-gen | User | {name: "rowlock"} |
INTERSECT
INTERSECT
returns a result set that includes only the distinct records common to all linear queries, filtering out any records that do not appear in every query.
MATCH ({_id: "U01"})-(u:User) RETURN u
INTERSECT
MATCH ({_id: "U03"})-(u:User) RETURN u
Result: u
_id | _uuid | schema | values |
---|---|---|---|
U02 | Sys-gen | User | {name: "Brainy"} |
INTERSECT ALL
INTERSECT ALL
returns a result set that includes only the records common to all linear queries without removing duplicates, filtering out any records that do not appear in every query.
MATCH ({_id: "U01"})-(u:User) RETURN u
INTERSECT ALL
MATCH ({_id: "U03"})-(u:User) RETURN u
Result: u
_id | _uuid | schema | values |
---|---|---|---|
U02 | Sys-gen | User | {name: "Brainy"} |
U02 | Sys-gen | User | {name: "Brainy"} |
OTHERWISE
OTHERWISE
returns the result set of the first query if it produces results. If the first query yields no results, it returns the result set of the second query, and so on, until a query with non-empty result set is found.
MATCH ({_id: "U04"})<-[]-(u:User) RETURN u
OTHERWISE
MATCH ({_id: "U02"})<-[]-(u:User) RETURN u
Result: u
_id | _uuid | schema | values |
---|---|---|---|
U01 | Sys-gen | User | {name: "rowlock"} |
U03 | Sys-gen | User | {name: "purplechalk"} |
U04 | Sys-gen | User | {name: "mochaeach"} |
In this example, the result set of the first linear query returns a null
value due to the usage of OPTIONAL
:
OPTIONAL MATCH ({_id: "U04"})<-[]-(u:User) RETURN u
OTHERWISE
MATCH ({_id: "U02"})<-[]-(u:User) RETURN u
Result:
u |
---|
null |
Renaming Return Items
You may use the AS
keyword to rename return items to ensure that the results of linear queries can be combined.
MATCH ({_id: "C01"})<-(u) RETURN u.name, 1 AS Club
UNION
MATCH ({_id: "C02"})<-(u) RETURN u.name, 2 AS Club
Result:
u.name | Club |
---|---|
Brainy | 1 |
lionbower | 1 |
mochaeach | 2 |
Using Different Query Conjunctions
MATCH (n:Club) RETURN n._id
OTHERWISE
MATCH (n) RETURN n._id
UNION ALL
MATCH (n)-[]->(:Club) RETURN n._id
Result:
n._id |
---|
C01 |
C02 |
U05 |
U04 |
U02 |
Deduplicating Multiple Return Items
When the RETURN
statements contain multiple return items, DISTINCT
removes duplicate records based on the combined values of all return items.
MATCH (u1 {name: "rowlock"})-(u2:User) RETURN u1.name, u2.name
UNION DISTINCT
MATCH (u1 {name: "purplechalk"})-(u2:User) RETURN u1.name, u2.name
Result:
u1.name | u2.name |
---|---|
rowlock | Brainy |
purplechalk | Brainy |
You may compare the results returned by UNION ALL
:
MATCH (u1 {name: "rowlock"})-(u2:User) RETURN u1.name, u2.name
UNION ALL
MATCH (u1 {name: "purplechalk"})-(u2:User) RETURN u1.name, u2.name
Result:
u1.name | u2.name |
---|---|
rowlock | Brainy |
rowlock | Brainy |
purplechalk | Brainy |
purplechalk | Brainy |