Cypher UNION - How to apply to collected lists

Viewed 39

Consider the following use of UNION cypher command:

MATCH (user:User)-[]-(org:Organization)
WHERE org.size > 100
RETURN collect({
   user.name,
   user.age
}) AS userList

UNION

MATCH (user:User)-[]-(family:Family)
WHERE family.mood = "Happy"
RETURN collect({
   user.name,
   user.age
}) AS userList

The UNION does not work, this query returns users only from the first MATCH. I suspect it's because of the collect statements, however the project's design requires the data to be collected. Is there a way to create a union of the collections, or perhaps collect after the union?

2 Answers

You can use apoc.coll.union of the APOC library, to create a union of two lists, like this:

MATCH (user:User)-[]-(org:Organization)
WHERE org.size > 100
WITH collect({
   user.name,
   user.age
}) AS userList1
MATCH (user:User)-[]-(family:Family)
WHERE family.mood = "Happy"
WITH userList1, collect({
   user.name,
   user.age
}) AS userList2
RETURN apoc.coll.union(userList1, userList2) AS userList

The function apoc.coll.union will not include duplicates, if you want to include duplicates use apoc.coll.unionAll.

Your query will work just fine except that you should 1) return a valid dictionary format and 2) use CALL which is a subquery for neo4j cypher.

RETURN  {
   name: user.name,
   age:  user.age
   } AS userList
 

See sample below:

CALL {MATCH (user:user{id:"some_id"}) 
RETURN {
  id: user.id, 
  age: user.age
}  AS userList
UNION
MATCH (user:user{id:"some_id2"}) 
RETURN  {
  id: user.id, 
  age: user.age
}  AS userList
} 
RETURN collect(userList) as userList

 Result:
╒══════════════════════════════════════════════════════════╕
│"userList"                                                │
╞══════════════════════════════════════════════════════════╡
│[{"id":"some_id","age":null},{"id":"some_id2","age":null}]│
└──────────────────────────────────────────────────────────┘

I am using neo4j version 4.4.3

Related