Reputation: 4918
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?
Upvotes: 9
Views: 15126
Reputation: 12627
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);
Upvotes: 0
Reputation: 30397
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.
Upvotes: 1
Reputation: 3882
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
Upvotes: 1
Reputation: 19
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
Upvotes: 1
Reputation: 2272
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
Upvotes: 2
Reputation: 4080
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.
Upvotes: 3
Reputation: 39915
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
Upvotes: 5