Skip to main content

Aggregations

Graphmind supports standard aggregation functions. Non-aggregated columns in RETURN become implicit grouping keys (like SQL GROUP BY).

Aggregate Functions

count()

-- Count all nodes
MATCH (n) RETURN count(n) AS total

-- Count by label
MATCH (n) RETURN labels(n) AS label, count(n) AS total
ORDER BY total DESC
labeltotal
[Person]200
[Post]2000
[Comment]3000

sum() and avg()

MATCH (p:Person)
RETURN sum(p.age) AS total_age, avg(p.age) AS average_age

min() and max()

MATCH (p:Person)
RETURN min(p.age) AS youngest, max(p.age) AS oldest

collect()

Aggregate values into a list:

MATCH (p:Person)-[:WORKS_AT]->(c:Company {name: "Acme Corp"})
RETURN collect(p.name) AS employees
employees
["Alice", "Bob", "Carol", ...]

Implicit GROUP BY

When you mix aggregated and non-aggregated expressions in RETURN, the non-aggregated ones become grouping keys:

-- Group by company, count employees per company
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
RETURN c.name AS company, count(p) AS headcount, avg(p.age) AS avg_age
ORDER BY headcount DESC
companyheadcountavg_age
Acme Corp4231.5
GlobalBank3829.8
DataStream1227.3
-- Group by city, find the oldest person per city
MATCH (p:Person)-[:LIVES_IN]->(c:City)
RETURN c.name AS city, max(p.age) AS max_age, count(p) AS population
ORDER BY population DESC
LIMIT 5

DISTINCT

Remove duplicate rows from results:

-- Unique cities where people live
MATCH (p:Person)-[:LIVES_IN]->(c:City)
RETURN DISTINCT c.name

DISTINCT applies to the entire row, not individual columns.

Combining Aggregations with WITH

Use WITH to aggregate first, then filter:

-- Companies with more than 10 employees
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
WITH c.name AS company, count(p) AS employees
WHERE employees > 10
RETURN company, employees
ORDER BY employees DESC
-- Most connected people (top 10 by friend count)
MATCH (p:Person)-[:KNOWS]->(f)
WITH p.name AS person, count(f) AS friends
ORDER BY friends DESC
LIMIT 10
RETURN person, friends

ORDER BY

Sort results by one or more columns:

-- Ascending (default)
MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age

-- Descending
MATCH (p:Person) RETURN p.name, p.age ORDER BY p.age DESC

-- Multiple columns
MATCH (p:Person)-[:LIVES_IN]->(c:City)
RETURN c.name, p.name, p.age
ORDER BY c.name ASC, p.age DESC

SKIP and LIMIT

Paginate through results:

-- First page (10 results)
MATCH (p:Person) RETURN p.name ORDER BY p.name LIMIT 10

-- Second page
MATCH (p:Person) RETURN p.name ORDER BY p.name SKIP 10 LIMIT 10

-- Third page
MATCH (p:Person) RETURN p.name ORDER BY p.name SKIP 20 LIMIT 10

Counting Relationships

-- Degree of each node (number of outgoing KNOWS edges)
MATCH (p:Person)-[r:KNOWS]->()
RETURN p.name, count(r) AS out_degree
ORDER BY out_degree DESC
LIMIT 5
p.nameout_degree
Alice8
Bob7
Carol6