Neo4j,获取一组节点之间的所有关系

时间:2014-08-08 12:41:39

标签: neo4j cypher

我有一个基于属性

获取节点的查询
MATCH (c { type: 'sometype' })
WITH c LIMIT 100
RETURN c

我想要的只是获取结果集中节点之间的所有关系,在IRC上有人告诉我使用:

MATCH (c { type: 'sometype'])
WITH c LIMIT 100
OPTIONAL MATCH (c)-[r]-()
RETURN c, r

但是这将包括从节点c到结果集之外的节点的关系,在我的情况下(几十万个关系)可能会产生非常大的无用结果集或性能问题)

有没有办法实现这个目标?

6 个答案:

答案 0 :(得分:3)

我想有多种方法可以做到这一点。一种方法是找到给定类型的所有节点并从中构建一个集合(cs)。然后再次匹配该组,这次与任何节点的传出关系并过滤以确保端节点在cs中:

MATCH (c {type:'sometype'})
WITH collect(c) as cs
MATCH (x {type:'sometype'})-[r]->(y)
WHERE y in cs
RETURN startNode(r).name, endNode(r).name

不知道您的图表模型,但我认为将属性type='sometype'重构为标签sometype可能是个好主意。在这种情况下,查询将如下所示:

MATCH (c:Group1)   
WITH collect(c) as cs
MATCH (x:Group1)-[r]->(y)
WHERE y in cs
RETURN startNode(r).name, endNode(r).name

答案 1 :(得分:3)

这是直截了当的。

MATCH (a)-[r]-(b)
WHERE a.type = 'foo' AND b.type = 'foo'
RETURN DISTINCT r

您可以同样使用新语法:

MATCH (a { type : 'foo' }) -[r] - (b {type : 'foo'})
RETURN DISTINCT r

如果你愿意的话。

答案 2 :(得分:1)

亚历克斯,

另一种解决方法是查询:

MATCH (c {type : 'sometype'})-[r:*0..1]-(d {type : 'sometype'})
WITH c, collect(r) as rs
RETURN c, rs

这允许没有这种关系的情况。

恩典与和平,

吉姆

答案 3 :(得分:1)

如果您使用标签而不是属性类型,那会更好。这将使用模式索引使您的查询非常快。

MATCH (a:SOMETYPE) -[r] - (b :SOMETYPE) RETURN DISTINCT r

答案 4 :(得分:1)

要尽量减少必要的匹配,您可以尝试:

MATCH (c { type: 'sometype'})
WITH c LIMIT 100
WITH COLLECT(c) as cNodes
UNWIND cNodes as c1
MATCH (c1)-[r]->(c2)
WHERE c2 in cNodes
RETURN c1, TYPE(r) as rel, c2

正如其他人所提到的,不推荐不带标签的匹配,因为必须扫描所有节点,因此随着db的大小增加,查询将变得越来越慢。如果可能的话,在初始匹配上使用标签,如果标签及其type属性上有索引,则这可能是一个非常快速的查询。

答案 5 :(得分:0)

我找到的最快的方式是:

 MATCH (n:NodeName {param:"7"})
        with n
        skip 0
        limit 5
        MATCH n-[r]->(k)
        with n,k,r

你也可以减少执行时间,例如代替n,k,r将使用 n.data,r.data,k.data

这是在Neo4j 2.3上测试的。