Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypher: Use UNWIND with potentially empty collection

Is there any way to use UNWIND for potentially empty collections (e.g. OPTIONAL UNWIND g)?

For instance, in the attached query it occurs that the collection (items) is empty sometimes (3rd block), but the results of the other collections are still relevant.

Here I want to crunch some numbers for a sub-graph and return the counts of various node types (group, users, location, item, itemgroups). The itemgroups can be derived via the items only. And because there are so many items attached to multiple users, it would be super slow if I include the itemgroups directly in the second block without aggregating first.

MATCH(group: Group {id: "12345"})
OPTIONAL MATCH(group) - [: IS_PARENT * 0..] - > (subgroup: Group)

WITH collect(distinct subgroup) as groups
UNWIND groups as group
  OPTIONAL MATCH(u: User) - [: BELONGS_TO] - > (group)
  OPTIONAL MATCH(u) --(i: Item)
  OPTIONAL MATCH(u) --(l: Location)
WITH groups, collect(distinct u) as users, collect(distinct i) as items, collect(distinct l) as locations
UNWIND items as i
  OPTIONAL MATCH(i) --(ig: FunctionalArea)
RETURN length(groups), length(users), length(items), length(locations), count(distinct ig)

I found a workaround, but I'm not really happy with that. When I insert a dummy node to the items collection, I can unwind it everytime without loosing results.

MATCH(group: Group {id: "12345"})
OPTIONAL MATCH(group) - [: IS_PARENT * 0..] - > (subgroup: Group)

WITH collect(distinct subgroup) as groups
UNWIND groups as group
  OPTIONAL MATCH(u: User) - [: BELONGS_TO] - > (group)
  OPTIONAL MATCH(u) --(i: Item)
  OPTIONAL MATCH(u) --(l: Location)
WITH groups, collect(distinct u) as users, collect(distinct i) as items, collect(distinct l) as locations

>> 
MATCH(ig:ItemGroup)
WITH groups, users, ([head(collect(ig))] + items) as items, locations
<<
UNWIND items as i
  OPTIONAL MATCH(i) --(ig: FunctionalArea)
RETURN length(groups), length(users), length(items), length(locations), count(distinct ig)

I'm considering writing two separate queries, but that would lead to complex client logic.

Any ideas and hints are very much appreciated.

Thanks!

like image 449
Sebastian Woinar Avatar asked Apr 24 '15 07:04

Sebastian Woinar


Video Answer


1 Answers

You could use:

UNWIND (CASE items WHEN [] then [null] else items end) as item

like image 131
Michael Hunger Avatar answered Oct 23 '22 10:10

Michael Hunger