Neo4j 可选匹配并不真正等同于 SQL 外连接
Neo4j optional match is NOT really equivalent to an SQL outer join
我想 return 一组中的所有行,只有其中一些与另一组有关系。例如,这是我的节点:
CREATE (n1:Union{UID:1})
CREATE (n2:Union{UID:2})
CREATE (n3:Union{UID:3})
CREATE (n4:Union{UID:4})
CREATE (n5:Union{UID:5})
CREATE (p1:Person{RN:1})
CREATE (p2:Person{RN:2})
CREATE (p3:Person{RN:3})
CREATE (p4:Person{RN:4})
CREATE (p5:Person{RN:5})
和关系
match (a:Union{UID:1}),(b:Person{RN:1})
create (a)-[:Child]->(b)
match (c:Union{UID:1}),(d:Person{RN:2})
create (c)-[:Child]->(d)
match (e:Union{UID:5}),(f:Person{RN:5})
create (e)-[:Child]->(f)
当我运行这个查询
optional match (u:Union)-[:Child*0..1]->(c:Person)
with u.UID as UID,case when c is not NULL then collect(c.RN) else NULL end as child
return UID,child order by UID
结果是
UID child
1 [1, 2]
5 [5]
我要找的是
UID Child
1 [1,2]
2 NULL
3 NULL
4 NULL
5 [5]
我该怎么做?
问题是你对整个模式进行了可选匹配,并期望它按照你想要的方式运行是不正确的(而且效率非常低,因为它必须匹配双方的所有节点).无论如何,您都需要在您想要的节点上进行匹配,然后在其余节点上进行可选匹配:
match (u:Union)
optional match (u)-[:Child*0..1]->(c:Person)
with u, collect(c.RN) as child
return u.UID as UID, case when size(child) = 0 then null else child end
order by UID
我想 return 一组中的所有行,只有其中一些与另一组有关系。例如,这是我的节点:
CREATE (n1:Union{UID:1})
CREATE (n2:Union{UID:2})
CREATE (n3:Union{UID:3})
CREATE (n4:Union{UID:4})
CREATE (n5:Union{UID:5})
CREATE (p1:Person{RN:1})
CREATE (p2:Person{RN:2})
CREATE (p3:Person{RN:3})
CREATE (p4:Person{RN:4})
CREATE (p5:Person{RN:5})
和关系
match (a:Union{UID:1}),(b:Person{RN:1})
create (a)-[:Child]->(b)
match (c:Union{UID:1}),(d:Person{RN:2})
create (c)-[:Child]->(d)
match (e:Union{UID:5}),(f:Person{RN:5})
create (e)-[:Child]->(f)
当我运行这个查询
optional match (u:Union)-[:Child*0..1]->(c:Person)
with u.UID as UID,case when c is not NULL then collect(c.RN) else NULL end as child
return UID,child order by UID
结果是
UID child
1 [1, 2]
5 [5]
我要找的是
UID Child
1 [1,2]
2 NULL
3 NULL
4 NULL
5 [5]
我该怎么做?
问题是你对整个模式进行了可选匹配,并期望它按照你想要的方式运行是不正确的(而且效率非常低,因为它必须匹配双方的所有节点).无论如何,您都需要在您想要的节点上进行匹配,然后在其余节点上进行可选匹配:
match (u:Union)
optional match (u)-[:Child*0..1]->(c:Person)
with u, collect(c.RN) as child
return u.UID as UID, case when size(child) = 0 then null else child end
order by UID