简体   繁体   中英

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:

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)

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 ). Then match again that group, this time with outgoing relationships to any node and filter that to make sure the endnode is in 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 . 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. 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.

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

This was tested on Neo4j 2.3

There's a APOC function for this - 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);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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