简体   繁体   English

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

[英]Neo4j, get all relationships between a set of nodes

I've a query that fetches nodes based on a property我有一个基于属性获取节点的查询

MATCH (c { type: 'sometype' })
WITH c LIMIT 100
RETURN c

all I want is to also fetch all the relations between nodes in the resultset, on IRC someone told me to use:我想要的只是获取结果集中节点之间的所有关系,在 IRC 上有人告诉我使用:

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

but that will include relationships from node c to nodes outside the resultset which in my case (some hundred thousand relationships) could create very big useless resultset or performance issues)但这将包括从节点 c 到结果集之外的节点的关系,在我的情况下(数十万个关系)可能会产生非常大的无用结果集或性能问题)

Is there any way to achieve that?有什么办法可以实现吗?

I guess there are multiple ways to do that. 我想有多种方法可以做到这一点。 One approach is to find all nodes for the given type and build a collection out of them ( cs ). 一种方法是找到给定类型的所有节点并从中构建集合( cs )。 Then match again that group, this time with outgoing relationships to any node and filter that to make sure the endnode is in cs : 然后再次匹配该组,这次与任何节点的传出关系并过滤以确保endnode在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

Don't know your graph model, but I think it could be a good idea to refactor the property type='sometype' into a label sometype . 不知道你的图模型,但我认为这可能是重构的财产是一个好主意type='sometype'成标签sometype In this case the query would look like this: 在这种情况下,查询将如下所示:

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

This is straight forward. 这是直截了当的。

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

You could equally use the new syntax: 您可以同样使用新语法:

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

If you prefer it. 如果你喜欢它。

alex, 亚历克斯,

Another way to approach this is this query: 另一种方法是这个查询:

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

This allows for the case where there are no relationships of this sort. 这允许没有这种关系的情况。

Grace and peace, 恩典与和平,

Jim 吉姆

It's better if you used labels instead of a property for type. 如果你使用标签而不是类型的属性,那就更好了。 This will make your queries very fast using schema indexes. 这将使用模式索引使您的查询非常快。

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

To minimize the matches necessary, you can try this: 要尽量减少必要的匹配,您可以尝试这样做:

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

As others have mentioned, a match without labels isn't recommended since all nodes must be scanned, so as the size of the db grows, the query will get slower and slower. 正如其他人所提到的,不推荐不带标签的匹配,因为必须扫描所有节点,因此随着db的大小增加,查询将变得越来越慢。 Use a label on the initial match if possible, and if there's an index on the label and its type property, this can be a very fast query. 如果可能,在初始匹配上使用标签,如果标签上有索引及其type属性,则这可能是一个非常快速的查询。

The most fastest way that i found is: 我找到的最快的方式是:

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

Also you can decrease execution time if for example instead of n,k,r will use n.data,r.data, k.data 你也可以减少执行时间,例如,如果不是n,k,r将使用n.data,r.data,k.data

This was tested on Neo4j 2.3 这是在Neo4j 2.3上测试的

There's a APOC function for this - apoc.algo.cover .为此有一个 APOC function - apoc.algo.cover

MATCH (n)
WHERE n.type = "sometype"
WITH collect(id(n)) as nodes
CALL apoc.algo.cover(nodes)
YIELD rel
RETURN  startNode(rel), rel, endNode(rel);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM