RETURN
The RETURN clause specifies what data to return from a query.
Basic Returns#
Return Nodes#
MATCH (u:User)
RETURN u
Return Properties#
MATCH (u:User)
RETURN u.name, u.age
Return All Properties#
MATCH (u:User)
RETURN u.*
Aliases#
Use aliases for clarity:
MATCH (u:User)
RETURN u.name AS userName, u.age AS userAge
Expressions#
Arithmetic#
MATCH (u:User)
RETURN u.name, u.age, u.age + 10 AS ageInTenYears
String Operations#
MATCH (u:User)
RETURN u.firstName + ' ' + u.lastName AS fullName
Conditional Expressions#
MATCH (u:User)
RETURN u.name,
CASE
WHEN u.age < 18 THEN 'Minor'
WHEN u.age < 65 THEN 'Adult'
ELSE 'Senior'
END AS ageGroup
Aggregations#
COUNT#
MATCH (u:User)
RETURN count(u) AS totalUsers
SUM, AVG, MIN, MAX#
MATCH (u:User)
RETURN avg(u.age) AS avgAge,
min(u.age) AS minAge,
max(u.age) AS maxAge
COLLECT#
MATCH (u:User)-[:KNOWS]->(f:User)
RETURN u.name, collect(f.name) AS friends
COUNT DISTINCT#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN count(DISTINCT u) AS activeUsers
Grouping#
Aggregations automatically group by non-aggregated fields:
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name, count(p) AS postCount
ORDER BY postCount DESC
Multiple grouping fields:
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.city, u.country, count(p) AS posts
DISTINCT#
Return unique results:
MATCH (u:User)-[:KNOWS]->(f:User)-[:KNOWS]->(fof:User)
RETURN DISTINCT fof.name
Relationships#
Return Relationships#
MATCH (u:User)-[r:KNOWS]->(f:User)
RETURN u, r, f
Relationship Properties#
MATCH (u:User)-[r:KNOWS]->(f:User)
RETURN u.name, f.name, r.since, r.strength
Relationship Type#
MATCH (u:User)-[r]->(other)
RETURN u.name, type(r), other.name
Paths#
Return Paths#
MATCH path = (u:User {name: 'Alice'})-[:KNOWS*1..3]->(f)
RETURN path
Path Length#
MATCH path = (u:User {name: 'Alice'})-[:KNOWS*]->(f:User {name: 'Bob'})
RETURN length(path) AS pathLength
Nodes in Path#
MATCH path = (u:User)-[:KNOWS*1..3]->(f)
RETURN nodes(path) AS pathNodes
Computed Values#
Counts and Sizes#
MATCH (u:User)
RETURN u.name,
size((u)-[:KNOWS]->()) AS friendCount
String Functions#
MATCH (u:User)
RETURN toLower(u.name) AS lowerName,
toUpper(u.email) AS upperEmail,
substring(u.name, 0, 1) AS initial
Date/Time Functions#
MATCH (p:Post)
RETURN p.title,
p.created,
datetime() - p.created AS age
Limiting Results#
Combine with LIMIT:
MATCH (u:User)
RETURN u.name, u.age
ORDER BY u.age DESC
LIMIT 10
Maps and Objects#
Return as Map#
MATCH (u:User)
RETURN {
name: u.name,
age: u.age,
email: u.email
} AS userInfo
Collect Maps#
MATCH (u:User)-[:KNOWS]->(f:User)
RETURN u.name,
collect({name: f.name, age: f.age}) AS friends
Pattern Comprehensions#
MATCH (u:User)
RETURN u.name,
[(u)-[:KNOWS]->(f) | f.name] AS friendNames,
[(u)-[:POSTED]->(p) | {title: p.title, date: p.created}] AS posts
Conditional Returns#
CASE Expression#
MATCH (u:User)
RETURN u.name,
CASE u.subscription
WHEN 'premium' THEN 'Premium User'
WHEN 'basic' THEN 'Basic User'
ELSE 'Free User'
END AS userType
CASE with Conditions#
MATCH (u:User)
RETURN u.name,
CASE
WHEN u.age < 18 THEN 'Youth discount'
WHEN u.age >= 65 THEN 'Senior discount'
ELSE 'Regular price'
END AS pricing
Complex Aggregations#
Multiple Aggregations#
MATCH (u:User)-[:POSTED]->(p:Post)
RETURN u.name,
count(p) AS posts,
avg(p.likes) AS avgLikes,
max(p.created) AS lastPost
Nested Aggregations#
MATCH (u:User)-[:POSTED]->(p:Post)
WITH u, count(p) AS postCount
WHERE postCount > 10
RETURN u.name, postCount
ORDER BY postCount DESC
Performance Tips#
- Return Only What You Need ```cypher -- Good: Return specific properties RETURN u.name, u.age
-- Bad: Return entire nodes when not needed RETURN u ```
-
Use DISTINCT Wisely
cypher -- DISTINCT can be expensive on large result sets RETURN DISTINCT u.city -
Limit Early
cypher -- Good: Filter before aggregation MATCH (u:User) WHERE u.active = true RETURN count(u) -
Project Early with WITH
cypher -- Good: Reduce data early MATCH (u:User)-[:POSTED]->(p:Post) WITH u, count(p) AS posts WHERE posts > 10 RETURN u.name, posts
Common Patterns#
Top N per Group#
MATCH (u:User)-[:POSTED]->(p:Post)
WITH u, p
ORDER BY p.created DESC
RETURN u.name, collect(p.title)[0..5] AS recentPosts
Pivot Data#
MATCH (u:User)-[:LIVES_IN]->(c:City)
RETURN c.name AS city,
count(u) AS population
ORDER BY population DESC
Running Totals#
MATCH (p:Post)
WITH p
ORDER BY p.created
RETURN p.title,
p.created,
sum(p.views) OVER (ORDER BY p.created) AS cumulativeViews
Next Steps#
- Match patterns with MATCH
- Filter results with WHERE
- Sort results with ORDER BY
- Limit results with LIMIT
- Read Cypher Introduction