Performance Cypher:对可能为空的集合使用“展开”

Performance Cypher:对可能为空的集合使用“展开”,performance,graph,neo4j,cypher,Performance,Graph,Neo4j,Cypher,是否有任何方法可以对可能为空的集合使用展开(例如,可选的展开g) 例如,在附加的查询中,有时集合(项)为空(第三个块),但其他集合的结果仍然相关 在这里,我想为一个子图计算一些数字,并返回各种节点类型(组、用户、位置、项目、项目组)的计数。 项目组只能通过项目派生。 而且,由于有太多的项目连接到多个用户,如果我直接在第二个块中包含项目组而不首先聚合,速度会非常慢 MATCH(group: Group {id: "12345"}) OPTIONAL MATCH(group) - [: IS_PAR

是否有任何方法可以对可能为空的集合使用展开(例如,可选的展开g)

例如,在附加的查询中,有时集合(项)为空(第三个块),但其他集合的结果仍然相关

在这里,我想为一个子图计算一些数字,并返回各种节点类型(组、用户、位置、项目、项目组)的计数。 项目组只能通过项目派生。 而且,由于有太多的项目连接到多个用户,如果我直接在第二个块中包含项目组而不首先聚合,速度会非常慢

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)
我找到了一个解决办法,但我对此并不满意。 当我向items集合插入一个虚拟节点时,每次都可以将其展开,而不会丢失结果

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)
匹配(组:组{id:“12345”})
可选匹配(组)-[:IS_PARENT*0..]->(子组:组)
以collect(不同的子组)作为组
将组作为组展开
可选匹配(u:用户)-[:属于]->(组)
可选匹配(u)--(i:项目)
可选匹配(u)--(l:位置)
对于组,收集(不同的u)作为用户,收集(不同的i)作为项目,收集(不同的l)作为位置
>> 
匹配(ig:ItemGroup)
使用组、用户、([head(collect(ig))]+项)作为项、位置

我建议您,不要使用这么多的“展开”,而是尝试重新组织您的查询

这是一个快速的重构,但只是一个建议;)请检查:

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

WITH COLLECT(DISTINCT subgroup) AS g, COLLECT(DISTINCT u) AS uc,
    count(distinct subgroup) as groups, 
    count(distinct u) as users, 
    count(distinct l) as locations

UNWIND uc as u

OPTIONAL MATCH(u) --(i: Item)
OPTIONAL MATCH(i) --(ig: FunctionalArea)

RETURN groups, users, count(DISTINCT i) AS items, locations, count(distinct ig)
子组也将收集独立的根组,bc*0。因此,第一个可选匹配不再是必需的

我尽可能早地清点了人数。只有第二级的用户才需要收集项目数据。享受:)

您可以使用:


作为项展开(CASE items WHEN[]然后[null]else items end)我遇到了同样的难题。我也去了
虚拟
节点根。它确实缺乏优雅,但似乎确实很管用。我很想听听其他可能的解决方案,尤其是更优雅的解决方案。甚至是具有新功能的
unwind coalesce(items,[null])as item
unwind coalesce(items,[null])as item
仅在items显式为null时才起作用。如果items是一个空集合,那么这种方法将不起作用。更好的解决方案如前所述,即
作为项目展开(案例项目在[]时,然后[null]否则项目结束)