9
votes

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?

6

6 Answers

2
votes

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

4
votes

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
3
votes

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.

1
votes

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
1
votes

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

1
votes

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.