我的Neo4j 3.2数据库有节点(n)
,可能与其他节点有:OWNER
个关系。我想找到具有(n)
关系的所有节点:OWNER
专门针对节点(a)
,(b)
和(c)
,特别是不发送到任何其他节点。
我原本以为用
可以很容易地完成MATCH (n), (o)
WHERE (
(n)-[:OWNER]->(o) AND o.uuid IN $owner_ids
AND NOT ((n)-[:OWNER]->(o) AND NOT o.uuid IN $owner_ids)
RETURN (n)
但它不起作用。此查询错误地将(n)
与:OWNER
,(a)
,(b)
,和 (c)
(d)
关系的节点MATCH (n), (o)
WHERE (n)-[:OWNER]->(o) AND o.uuid IN $owner_ids
WITH (n),(o)
WHERE NOT ((n)-[:OWNER]->(o) AND NOT o.uuid IN $owner_ids)
RETURN (n)
返回。我也试过了
MATCH (a)<-[:ANSWER]-(:Person {uuid: $person_id}), (o)
WHERE (exists((o)<-[:OWNER]-(:Owner)<-[:OWNER]-(:Form)-[:ANSWER]->(a)) AND o.uuid IN $owner_ids)
AND NOT (exists((o)<-[:OWNER]-(:Owner)<-[:OWNER]-(:Form)-[:ANSWER]->(a)) AND NOT o.uuid IN $owner_ids)
RETURN (a)
除了感觉像其他一百万个其他排列一样无济于事。非常感谢任何建议!
以上是一个简化的方案。根据评论中的要求,更接近现实的一个例子是:
MATCH (o)<-[:OWNER]-(:Owner)<-[:OWNER]-(:Form)-[:ANSWER]->(a)<-[:ANSWER]-(:Person {uuid: $person_id})
WHERE o.uuid IN $owner_ids
WITH (a), count(o) as cnt
WHERE cnt = size(()<-[:OWNER]-(:Owner)<-[:OWNER]-(:Form)-[:ANSWER]->(a))
RETURN (a)
完整的答案是
def g():
a = {}
b = 0
def f():
a[0] = b
f()
print(a)
return a
a = g()
print(a)
答案 0 :(得分:1)
假设您在图表中添加标签(现在让我们使用:Node,虽然从描述中不清楚所有节点是否应该相同,或者某些节点应该使用不同的标签),并且您对以下内容有一个独特的约束:节点(uuid)用于快速查找,这应该工作:
MATCH (n:Node)-[:OWNER]->(o:Node)
WHERE o.uuid IN $owner_ids
WITH n, count(o) as cnt
WHERE cnt = size((n)-[:OWNER]->())
RETURN n
您的查询在n
和o
(图表中所有节点的交叉产品)之间有一个笛卡尔积,won't perform well。您需要在MATCH中指定关系,而不是WHERE。
至于查询的其余部分,我们为每个n
获取o
个节点(具有相关ID的节点)的数量,并确保数量:OWNER每个n
的关系等于该计数。如果它更大,则存在:与其他节点的OWNER关系,因此将其过滤掉。
我们正在使用的size()
函数,因为我们没有为结束节点指定任何内容,efficient at getting relationship counts。
答案 1 :(得分:0)
如果您的要求是全部三个:OWNER关系存在(不只是它们的任何子集),那么我将使用此查询:
WITH ['a', 'b', 'c'] AS ids
MATCH (n:Node)-[:OWNER]->(o:Node)
WITH n,
COUNT(CASE WHEN o.uuid IN ids THEN 1 END) AS matches_found,
size(ids) AS matches_desired,
count(o) AS total_relationships
WHERE matches_found = matches_desired
AND matches_found = total_relationships
RETURN n
ORDER BY n.uuid