Neo4j 查找与节点(a)、(b)和(c)具有所有者关系的节点(n),而不查找其他节点

Neo4j 查找与节点(a)、(b)和(c)具有所有者关系的节点(n),而不查找其他节点,neo4j,cypher,Neo4j,Cypher,我的Neo4j 3.2数据库有节点(n),这些节点可能与其他节点有:OWNER关系。我想查找所有节点(n),它们与:所有者的关系特别是与节点(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) RETU

我的Neo4j 3.2数据库有节点
(n)
,这些节点可能与其他节点有
:OWNER
关系。我想查找所有节点
(n)
,它们与
:所有者
的关系特别是与节点
(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)
,其中
:所有者
(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(a)假设您将标签添加到图形中(现在让我们使用:Node,尽管从您的描述中不清楚是否所有节点都应该相同,或者是否有些节点应该使用不同的标签),并且您对: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
之间的笛卡尔积(图中所有节点之间的叉积),这是一个。您需要指定匹配中的关系,而不是WHERE

至于查询的其余部分,对于每个
n
,我们将获得
o
节点的计数(那些具有问题ID的节点),并确保每个
n
的:所有者关系数等于该计数。如果更大,则有:所有者与其他节点的关系,因此这些关系被过滤掉


我们使用的
size()
函数是。

如果您的要求是所有三个:所有者关系都存在(而不仅仅是它们的任何子集),那么我会使用以下查询:

  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

它看起来不像是在图中使用标签,这会大大降低查询速度(因为每个节点的匹配都需要扫描图中的所有节点),并且不能使用没有标签的索引。请在图表中添加标签并更新描述。@InverseFalcon,在发布之前,我将问题归结为我认为的核心问题。不过,我已经用一个更接近真实的问题更新了我的问题。谢谢,我将开始更新我的答案。注意匹配中带有
o
的笛卡尔积,并确保解释(或配置)查询以查看查询计划。看起来您的图形有:物品所有者(如:表单),但:所有者也有:所有者?是否正确?@InverseFalcon,使用实际的
(:Owner)
节点是因为关系本身不能有关系或多个标签。
(:Owner)
节点实际上是关系的一部分。
(o)
节点是所有者,它是多态的。GENIOUS!!!非常感谢你!!我想我已经研究这个问题两个小时了。这么好的解决方案!刚刚测试过,绝对有效!伟大的看来我根本不需要修改答案。很乐意帮忙!
  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