RETURN and Aggregation
Transform and aggregate query results.
RETURN Clause
Returning Nodes
Returning Properties
// Single property
MATCH (p:Person)
RETURN p.name
// Multiple properties
MATCH (p:Person)
RETURN p.name, p.age, p.email
Aliases
// Using AS keyword
MATCH (p:Person)
RETURN p.name AS personName, p.age AS years
// Implicit alias (without AS - not recommended)
MATCH (p:Person)
RETURN p.name personName
Distinct Results
Expressions
// Computed values
MATCH (p:Person)
RETURN p.name, p.age + 1 AS nextYearAge
// String concatenation
MATCH (p:Person)
RETURN p.firstName + ' ' + p.lastName AS fullName
Arithmetic uses + - * / % ^ with standard precedence; see
Numeric Functions.
Standalone RETURN
A query can consist of just a RETURN (no MATCH), which is handy for
evaluating expressions:
Aggregation Functions
COUNT
// Count all matches
MATCH (p:Person)
RETURN COUNT(p) AS personCount
// Count non-NULL values
MATCH (p:Person)
RETURN COUNT(p.email) AS withEmail
// Count all rows (including NULLs)
MATCH (p:Person)
RETURN COUNT(*) AS total
// Count distinct
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
RETURN COUNT(DISTINCT c.name) AS companyCount
SUM
// Total of all ages
MATCH (p:Person)
RETURN SUM(p.age) AS totalAge
// Total salary by department
MATCH (e:Employee)
RETURN e.department, SUM(e.salary) AS totalSalary
AVG
// Average age
MATCH (p:Person)
RETURN AVG(p.age) AS averageAge
// Average by group
MATCH (p:Person)
RETURN p.city, AVG(p.age) AS avgAge
MIN / MAX
// Minimum and maximum
MATCH (p:Person)
RETURN MIN(p.age) AS youngest, MAX(p.age) AS oldest
// By city
MATCH (p:Person)
RETURN p.city, MIN(p.age), MAX(p.age)
COLLECT
// Collect into list
MATCH (p:Person)
RETURN COLLECT(p.name) AS allNames
// Collect with filter
MATCH (p:Person)
WHERE p.city = 'NYC'
RETURN COLLECT(p.name) AS nyNames
// Nested collect
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
RETURN c.name, COLLECT(p.name) AS employees
Standard Deviation
// Sample standard deviation
MATCH (p:Person)
RETURN stdDev(p.age) AS ageStdDev
// Population standard deviation
MATCH (p:Person)
RETURN stdDevP(p.age) AS agePopulationStdDev
Percentiles
// Continuous percentile (interpolated)
MATCH (p:Person)
RETURN percentileCont(p.age, 0.5) AS medianAge
// Discrete percentile (actual value)
MATCH (p:Person)
RETURN percentileDisc(p.age, 0.9) AS p90Age
Grouping Results
Implicit Grouping
// Group by company
MATCH (p:Person)-[:WORKS_AT]->(c:Company)
RETURN c.name, AVG(p.age) AS avgAge
// Multiple group keys
MATCH (p:Person)
RETURN p.city, p.department, COUNT(*) AS count
WITH for Pre-aggregation
// Filter after aggregation
MATCH (p:Person)
WITH p.city AS city, COUNT(*) AS cityCount
WHERE cityCount > 10
RETURN city, cityCount
Advanced Return Patterns
Conditional Values
// Using CASE
MATCH (p:Person)
RETURN p.name,
CASE
WHEN p.age < 18 THEN 'minor'
WHEN p.age < 65 THEN 'adult'
ELSE 'senior'
END AS category
Complex Expressions
// Computed columns
MATCH (p:Person)
RETURN
p.name,
p.age,
p.age * 12 AS ageInMonths,
date().year - p.birthYear AS calculatedAge
Returning Maps
// Create map from properties
MATCH (p:Person)
RETURN {
name: p.name,
age: p.age,
city: p.city
} AS personMap
Returning Paths
// Return full path
MATCH p = (a:Person)-[:KNOWS*1..3]->(b:Person)
RETURN p, length(p) AS hops
// Path nodes and relationships
MATCH p = (a:Person)-[:KNOWS]->(b:Person)
RETURN nodes(p) AS pathNodes, relationships(p) AS pathRels
Path Functions
nodes()
Returns a list of all nodes in a path.
MATCH p = (a:Person {name: 'Alice'})-[:KNOWS*1..3]->(b:Person)
RETURN nodes(p) as pathNodes
// [(:Person {name: 'Alice'}), (:Person {...}), ...]
// Count nodes in path
MATCH p = shortestPath((a)-[:KNOWS*]-(b))
RETURN size(nodes(p)) as nodeCount
relationships()
Returns a list of all relationships in a path.
MATCH p = (a:Person {name: 'Alice'})-[:KNOWS*1..3]->(b:Person)
RETURN relationships(p) as pathRels
// [(:KNOWS {...}), (:KNOWS {...}), ...]
// Get relationship types
MATCH p = (a)-[*1..3]-(b)
RETURN [r IN relationships(p) | type(r)] as relTypes
length()
Returns the number of relationships in a path. length() also accepts a string
or list and returns its length.
Graph and Scalar Functions
These functions inspect nodes and relationships:
| Function | Returns |
|---|---|
labels(n) |
List of a node's labels |
type(r) |
A relationship's type |
properties(x) |
Property map of a node/relationship (or the map itself) |
keys(x) |
List of property names |
id(x) |
Integer identity of a node/relationship |
elementId(x) |
Identity as a string |
startNode(r) / endNode(r) |
The source / target node of a relationship |
MATCH (n:Person {name: 'Alice'})
RETURN labels(n) AS labels, properties(n) AS props, id(n) AS id
MATCH ()-[r]->()
RETURN type(r) AS rel_type, startNode(r).name AS from, endNode(r).name AS to
labels() can also be used as a filter, e.g. WHERE 'Admin' IN labels(n).
Common Use Cases
Dashboard Metrics
// User statistics
MATCH (u:User)
RETURN
COUNT(*) AS totalUsers,
COUNT(u.verifiedEmail) AS verifiedUsers,
AVG(u.loginCount) AS avgLogins,
MAX(u.lastLogin) AS mostRecentLogin
Reports
// Monthly signups
MATCH (u:User)
WITH date.truncate('month', u.createdAt) AS month, COUNT(*) AS signups
RETURN month, signups
ORDER BY month