如何根据另一组节点的传入关系和一些特殊条件确定一组节点

时间:2014-04-16 00:49:32

标签: neo4j cypher

我有一个Cypher查询,它获取了一组节点' n'类型'#,说(它通过图中的许多不同节点类型来实现这一点)。

如果我们假设以下内容:

  • t类节点的其余部分是集合' m,因此m和n之间没有相交。
  • 类型t节点之间有多种类型的关系。

我有特定的关系' r'我对此感兴趣。在这个具体案例中,我知道以下事实:

  • 类型t节点可以有0个或更多这些r关系,传入/传出。
  • 集合n中的节点没有设置m
  • 的传出r关系
  • 集合m中的节点可能具有设置m或n的传出r关系。

我设置了n,我试图确定来自集合m的节点满足以下条件:

  • 有0个关系 OR
  • 只有r关系才能设置n,但不能设置为集m中的任何节点。

一些示例数据:

输入t节点:

n1,n2,n3 m1,m2,m3

输入r关系

m1(没有关系) m2-> n1,m2-> n2 m3-> n3,m3-> m2

结果应该返回m1和m2,但不是m3。

我对Cypher很新,所以请根据需要随意指出相关文档。另外,如果你能解释一下你确定答案的过程,我会很感激,因为我怀疑我在这里并不太了解一些简单的东西。

1 个答案:

答案 0 :(得分:3)

你的例子比数据的模型更多,你可能知道如何分辨m:s和n:s但我不能仅仅在标识符上写一个查询,必须有一些实际的数据或结构来区别。对于isntance,假设图中的所有节点都是t类型,设置nm可以通过标签:N:M区分,让标识符为使用属性uid的值(使查询结果与您的问题对应),并将类型r关系设为[:R],然后使用

创建图表
CREATE 
  (n1:N{uid:"n1"}), (n2:N{uid:"n2"}), (n3:N{uid:"n3"})
  ,(m1:M{uid:"m1"}), (m2:M{uid:"m2"}), (m3:M{uid:"m3"})
  , m2-[:R]->n1, m2-[:R]->n2
  , m3-[:R]->n3, m3-[:R]->m2

查询可能看起来像

MATCH (n:N)                   // bind each node in the set n
WITH collect(n) AS nn         // collect and treat them as a set nn
MATCH (m:M)                   // grab each node in the set m
OPTIONAL MATCH m-[:R]->(x)    // optionally expand from m to unknown by r
WITH nn, m, collect(x) AS xx  // collect unknown per m as xx where
WHERE ALL (x IN xx            // all unknown nodes are in the nn set
           WHERE x IN nn)     // (if m has no -[:R]-> then the set xx is empty
                              //   and the condition is true–i.e. 
                              //   either m has no outgoing r or
                              //   the other node is in nn)
RETURN m

结果

m
(3:M {uid:"m1"})
(4:M {uid:"m2"})

您可以尝试查询here