查找节点(n):与节点(a),(b)和(c)的OWNER关系,没有其他节点

时间:2017-09-09 19:28:58

标签: neo4j cypher

我的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)

ANSWER

完整的答案是

def g():
    a = {}
    b = 0
    def f():
        a[0] = b
    f()
    print(a)
    return a
a = g()
print(a)

2 个答案:

答案 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

您的查询在no(图表中所有节点的交叉产品)之间有一个笛卡尔积,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