Does Cypher has functions like Group By?

时间:2019-01-18 18:57:56

标签: sql neo4j group-by cypher

I am new to Neo4j and wondering if Cypher has functions like GROUP BY in SQL.

Here is my code:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
RETURN m.title AS movie, p.name AS actor 

Here is my result from above query:

movie                       actor

"The Matrix"                "Emil Eifrem"
"The Matrix"                "Carrie-Anne Moss"
"The Matrix"                "Keanu Reeves"
"The Matrix Reloaded"       "Hugo Weaving"
"The Matrix Reloaded"       "Laurence Fishburne"
"The Matrix Revolutions"    "Hugo Weaving"
"The Matrix Revolutions"    "Laurence Fishburne"

Here is the result I want to have:

movie                       actor                  num_of_actors

"The Matrix"                "Emil Eifrem"           3
"The Matrix"                "Carrie-Anne Moss"      3
"The Matrix"                "Keanu Reeves"          3
"The Matrix Reloaded"       "Hugo Weaving"          2
"The Matrix Reloaded"       "Laurence Fishburne"    2
"The Matrix Revolutions"    "Hugo Weaving"          2
"The Matrix Revolutions"    "Laurence Fishburne"    2

Basically I would like to have the number of actors played in each movie together with the original results.

Thanks in advance

1 个答案:

答案 0 :(得分:1)

You'll want to review the aggregation functions, which you can use within a WITH clause to do grouping.

For example, if you wanted to group the actor names with each movie, you could do this:

MATCH (p:Person)-[:ACTED_IN]->(m:Movie)
WITH m, collect(p.name) as actors
RETURN m.title AS movie, actors

That said, there are some shortcuts we can do here since you're asking about the total number of actors per movie (see our knowledge base article on using degree counts from a node instead of doing expansions).

If you wanted to keep a separate row per actor, but also have the number of actors, since we know :ACTED_IN relationships will never go to the same actor more than once, we can get the degree of :ACTED_IN relationships incoming to each :Movie node to get our count. For best performance, get the degree before you expand out to actors:

MATCH (m:Movie)
WITH m, m.title as title, size((m)<-[:ACTED_IN]-()) as num_of_actors
MATCH (p:Person)-[:ACTED_IN]->(m)
RETURN title, p.name as actor, num_of_actors