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#

  1. Return Only What You Need ```cypher -- Good: Return specific properties RETURN u.name, u.age

-- Bad: Return entire nodes when not needed RETURN u ```

  1. Use DISTINCT Wisely cypher -- DISTINCT can be expensive on large result sets RETURN DISTINCT u.city

  2. Limit Early cypher -- Good: Filter before aggregation MATCH (u:User) WHERE u.active = true RETURN count(u)

  3. 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#