Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

cypher subquery: get node with max/min value and process it

Tags:

neo4j

cypher

I struggle to return the node with the largest value, and process that node further.

Here's how I would return a node with the largest value:

START n=node(startnode)
MATCH n-[:TYPE]-m
RETURN m
ORDER BY m.value DESC LIMIT 1

but now I am in a subquery

START n=node(somenode)
MATCH n-[:TYPE1]-q
WITH DISTINCT q
MATCH q-[:TYPE2]-m

and then the ORDER BY .. LIMIT 1 obviously doesn't work anymore because I want one result for each q. How is this done?

Also, once I have the m with largest value for each q I'll also need to process it:

RETURN q, m.maxvalue, x.anothervalue

from

MATCH m-[:HAS_ONE_LINK_TO]->x

So while I've been playing with collections (collect(m) ), I haven't figured a way to expand them back to "result rows" for applying that MATCH.

like image 667
bebbi Avatar asked Jul 19 '13 13:07

bebbi


People also ask

How do you perform aggregation in Cypher?

The Cypher query offers aggregation similar to GROUP BY offered by SQL. The aggregate function can take multiple values and can calculate the aggregated values for them. In this recipe, we will learn the common aggregation techniques, with the help of examples.

How do you count nodes in Cypher?

Using count(*) to return the number of nodes The function count(*) can be used to return the number of nodes; for example, the number of nodes connected to some node n . The labels and age property of the start node n and the number of nodes related to n are returned.

What Cypher syntax do you use to create a subquery?

CALL {} (subquery)

How do you write a Cypher query?

Cypher uses an ASCII-art type of syntax where (nodes)-[:ARE_CONNECTED_TO]->(otherNodes) using rounded brackets for circular (nodes) , and -[:ARROWS]-> for relationships. When you write a query, you draw a graph pattern through your data.


1 Answers

Untested... let me know if it works for you:

START n=node(somenode)
MATCH n-[:TYPE1]-q                // initial query
WITH DISTINCT q
MATCH q-[:TYPE2]-m
WITH q, max(m.value) as max       // get max for q
MATCH q-[:TYPE2]-m                
WHERE m.value = max               // find the max m for each q
WITH q, m
MATCH m-[:HAS_ONE_LINK_TO]->x     // find x from m
RETURN q, m, x

Edit: because of recent upvotes on this old answer... please consider a fresher query written in 3.x era using collect/unwind -- also untested (take care to not do this if the number of ms will be quite large, as they may be stored in the partial result of the query instead of being able to stream them):

MATCH (n:Label)-[:TYPE1]-(q)                  // initial query
WITH DISTINCT q
MATCH (q)-[:TYPE2]-(m)
WITH q, max(m.value) as max, collect(m) as ms // get max for q, collect ms
UNWIND ms as m
WHERE m.value = max
MATCH (m)-[:HAS_ONE_LINK_TO]->(x)             // find x from m
RETURN q, m, x
like image 165
Eve Freeman Avatar answered Oct 18 '22 13:10

Eve Freeman