Examples

This page provides ready-to-run Cypher queries with sample output. All examples use the same small sample graph defined below.


Sample Graph

Every example on this page queries the following graph file (examples/team.json):

{
  "nodes": [
    { "key": "alice", "attributes": { "label": "Person", "name": "Alice", "role": "Engineer", "department": "Backend", "age": 30, "email": "alice@co.com" } },
    { "key": "bob", "attributes": { "label": "Person", "name": "Bob", "role": "Engineer", "department": "Frontend", "age": 25 } },
    { "key": "charlie", "attributes": { "label": "Person", "name": "Charlie", "role": "Designer", "department": "Design", "age": 35, "email": "charlie@co.com" } },
    { "key": "diana", "attributes": { "label": "Person", "name": "Diana", "role": "Manager", "department": "Backend", "age": 40, "email": "diana@co.com" } },
    { "key": "eve", "attributes": { "label": "Person", "name": "Eve", "role": "Engineer", "department": "Backend", "age": 28 } },
    { "key": "frank", "attributes": { "label": "Person", "name": "Frank", "role": "Designer", "department": "Design", "age": 32 } }
  ],
  "edges": [
    { "source": "alice", "target": "bob", "attributes": { "type": "WORKS_WITH" } },
    { "source": "alice", "target": "charlie", "attributes": { "type": "WORKS_WITH" } },
    { "source": "alice", "target": "eve", "attributes": { "type": "WORKS_WITH" } },
    { "source": "bob", "target": "charlie", "attributes": { "type": "WORKS_WITH" } },
    { "source": "diana", "target": "alice", "attributes": { "type": "MANAGES" } },
    { "source": "diana", "target": "eve", "attributes": { "type": "MANAGES" } }
  ]
}

Visual structure

Diana (Manager, Backend, 40)
  └─MANAGES─> Alice (Engineer, Backend, 30)
              ├─WORKS_WITH─> Bob (Engineer, Frontend, 25)
              │               └─WORKS_WITH─> Charlie (Designer, Design, 35)
              ├─WORKS_WITH─> Charlie
              └─WORKS_WITH─> Eve (Engineer, Backend, 28)
  └─MANAGES─> Eve

Frank (Designer, Design, 32) — no connections

All examples use --format rows for clean, predictable row-based JSON output.


Basic Node Queries

1. Find nodes by label and property filter

Find every person with the role Engineer:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {role: "Engineer"}) RETURN p.name, p.department' --format rows

Output:

[
  { "name": "Alice", "department": "Backend" },
  { "name": "Bob", "department": "Frontend" },
  { "name": "Eve", "department": "Backend" }
]

2. Find a node by property value

Look up a specific person by name:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"}) RETURN p.name, p.role, p.department' --format rows

Output:

[
  { "name": "Alice", "role": "Engineer", "department": "Backend" }
]

3. Count all nodes

Count every node in the graph regardless of label:

gcyphrq -g examples/team.json -e 'MATCH (n) RETURN count(n) AS totalNodes' --format rows

Output:

[
  { "totalNodes": 6 }
]

4. Count all edges

Count every edge in the graph regardless of type:

gcyphrq -g examples/team.json -e 'MATCH ()-[r]->() RETURN count(r) AS totalEdges' --format rows

Output:

[
  { "totalEdges": 6 }
]

5. Alias projections

Rename columns in the output with AS:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.role = "Designer" RETURN p.name AS fullName, p.role AS jobTitle, p.department AS team' --format rows

Output:

[
  { "fullName": "Charlie", "jobTitle": "Designer", "team": "Design" },
  { "fullName": "Frank", "jobTitle": "Designer", "team": "Design" }
]

Relationship Queries

6. Outbound relationships

Find everyone Alice collaborates with (outbound WORKS_WITH edges only):

gcyphrq -g examples/team.json -e 'MATCH (a:Person {name: "Alice"})-[:WORKS_WITH]->(p) RETURN a.name AS source, p.name AS target' --format rows

Output:

[
  { "source": "Alice", "target": "Bob" },
  { "source": "Alice", "target": "Charlie" },
  { "source": "Alice", "target": "Eve" }
]

7. Inbound relationships

Find who manages Alice (inbound MANAGES edge):

gcyphrq -g examples/team.json -e 'MATCH (a:Person {name: "Alice"})<-[r:MANAGES]-(m:Person) RETURN m.name AS manager, a.name AS report' --format rows

Output:

[
  { "manager": "Diana", "report": "Alice" }
]

8. Undirected relationships

Find all people directly connected to Alice, regardless of edge direction:

gcyphrq -g examples/team.json -e 'MATCH (a:Person {name: "Alice"})-[r]-(p) RETURN a.name AS source, p.name AS target' --format rows

Output:

[
  { "source": "Alice", "target": "Diana" },
  { "source": "Alice", "target": "Bob" },
  { "source": "Alice", "target": "Charlie" },
  { "source": "Alice", "target": "Eve" }
]

9. Variable-length paths (direct reports only)

Find everyone Diana manages directly (1-hop outbound):

gcyphrq -g examples/team.json -e 'MATCH (d:Person {name: "Diana"})-[r*1..1]->(p:Person) RETURN d.name AS start, p.name AS reachable' --format rows

Output:

[
  { "start": "Diana", "reachable": "Alice" },
  { "start": "Diana", "reachable": "Eve" }
]

10. Variable-length paths (multi-hop)

Find everyone reachable from Diana within 2 hops (includes Alice’s collaborators):

gcyphrq -g examples/team.json -e 'MATCH (d:Person {name: "Diana"})-[r*1..2]->(p:Person) RETURN d.name AS start, p.name AS reachable' --format rows

Output:

[
  { "start": "Diana", "reachable": "Alice" },
  { "start": "Diana", "reachable": "Bob" },
  { "start": "Diana", "reachable": "Charlie" },
  { "start": "Diana", "reachable": "Eve" },
  { "start": "Diana", "reachable": "Eve" }
]

Note: Eve appears twice because there are two distinct paths to her: Diana → Eve (1-hop) and Diana → Alice → Eve (2-hop). Variable-length paths return one row per path, not per unique node.

11. Count outbound connections for a node

Count how many direct outbound connections Alice has:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"})-[]->(t) RETURN count(t) AS connections' --format rows

Output:

[
  { "connections": 3 }
]

Filtering with WHERE

12. Comparison operators

Find people older than 30, sorted by age:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.age > 30 RETURN p.name, p.age ORDER BY p.age ASC' --format rows

Output:

[
  { "name": "Frank", "age": 32 },
  { "name": "Charlie", "age": 35 },
  { "name": "Diana", "age": 40 }
]

13. NOT equal (<>)

Find everyone except Alice:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.name <> "Alice" RETURN p.name' --format rows

Output:

[
  { "name": "Bob" },
  { "name": "Charlie" },
  { "name": "Diana" },
  { "name": "Eve" },
  { "name": "Frank" }
]

14. AND

Find Backend Engineers:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.role = "Engineer" AND p.department = "Backend" RETURN p.name' --format rows

Output:

[
  { "name": "Alice" },
  { "name": "Eve" }
]

15. OR

Find Managers or Designers:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.role = "Manager" OR p.role = "Designer" RETURN p.name, p.role' --format rows

Output:

[
  { "name": "Charlie", "role": "Designer" },
  { "name": "Diana", "role": "Manager" },
  { "name": "Frank", "role": "Designer" }
]

16. NOT

Find everyone who is not in the Backend department:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE NOT p.department = "Backend" RETURN p.name, p.department ORDER BY p.name ASC' --format rows

Output:

[
  { "name": "Bob", "department": "Frontend" },
  { "name": "Charlie", "department": "Design" },
  { "name": "Frank", "department": "Design" }
]

17. Parenthesized precedence

Find Engineers who are either over 32 or under 26:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE (p.age > 32 OR p.age < 26) AND p.role = "Engineer" RETURN p.name, p.age' --format rows

Output:

[
  { "name": "Bob", "age": 25 }
]

18. CONTAINS

Find people in a department whose name contains “ack” (matches “Backend”):

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.department CONTAINS "ack" RETURN p.name, p.department' --format rows

Output:

[
  { "name": "Alice", "department": "Backend" },
  { "name": "Diana", "department": "Backend" },
  { "name": "Eve", "department": "Backend" }
]

19. IS NOT NULL

Find people who have an email address:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.email IS NOT NULL RETURN p.name, p.email' --format rows

Output:

[
  { "name": "Alice", "email": "alice@co.com" },
  { "name": "Charlie", "email": "charlie@co.com" },
  { "name": "Diana", "email": "diana@co.com" }
]

20. IS NULL

Find people without an email address:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.email IS NULL RETURN p.name' --format rows

Output:

[
  { "name": "Bob" },
  { "name": "Eve" },
  { "name": "Frank" }
]

Aggregations

21. Group and count with WITH

Count how many direct reports each manager has:

gcyphrq -g examples/team.json -e 'MATCH (m:Person)-[:MANAGES]->(e:Person) WITH m, count(e) AS teamSize RETURN m.name, teamSize' --format rows

Output:

[
  { "name": "Diana", "teamSize": 2 }
]

22. Aggregate functions

Compute statistics across all Engineers:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {role: "Engineer"}) RETURN count(p) AS totalEngineers, sum(p.age) AS totalAge, min(p.age) AS youngest, max(p.age) AS oldest, avg(p.age) AS avgAge' --format rows

Output:

[
  { "totalEngineers": 3, "totalAge": 83, "youngest": 25, "oldest": 30, "avgAge": 27.666666666666668 }
]

Note: avg() returns a floating-point value. Use round() in your application code if you need a specific precision.

23. WHERE on WITH

Find people with more than 1 outbound connection, ranked by connection count:

gcyphrq -g examples/team.json -e 'MATCH (p:Person)-[]->(t:Person) WITH p, count(t) AS outDegree WHERE outDegree > 1 RETURN p.name, outDegree ORDER BY outDegree DESC' --format rows

Output:

[
  { "name": "Alice", "outDegree": 3 },
  { "name": "Diana", "outDegree": 2 }
]

Optional Matching

24. OPTIONAL MATCH

Find everyone and their direct reports — people with no reports still appear with null:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) OPTIONAL MATCH (p)-[:MANAGES]->(r:Person) RETURN p.name AS person, r.name AS report' --format rows

Output:

[
  { "person": "Alice", "report": null },
  { "person": "Bob", "report": null },
  { "person": "Charlie", "report": null },
  { "person": "Diana", "report": "Alice" },
  { "person": "Diana", "report": "Eve" },
  { "person": "Eve", "report": null },
  { "person": "Frank", "report": null }
]

Sorting and Pagination

25. ORDER BY

List Engineers sorted by age (oldest first):

gcyphrq -g examples/team.json -e 'MATCH (p:Person) WHERE p.role = "Engineer" RETURN p.name, p.age ORDER BY p.age DESC' --format rows

Output:

[
  { "name": "Alice", "age": 30 },
  { "name": "Eve", "age": 28 },
  { "name": "Bob", "age": 25 }
]

26. LIMIT

Get the first 3 people alphabetically:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name ORDER BY p.name ASC LIMIT 3' --format rows

Output:

[
  { "name": "Alice" },
  { "name": "Bob" },
  { "name": "Charlie" }
]

27. SKIP + LIMIT (pagination)

Get page 2 (skip first 2, take next 2):

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name ORDER BY p.name ASC SKIP 2 LIMIT 2' --format rows

Output:

[
  { "name": "Charlie" },
  { "name": "Diana" }
]

Mutations

Mutations modify the graph in-memory during query execution. They do not persist to the original file.

28. CREATE

Add a new person to the graph:

gcyphrq -g examples/team.json -e 'CREATE (n:Person {name: "Grace", role: "Engineer", department: "Frontend", age: 27}) RETURN n.name, n.role, n.department' --format rows

Output:

[
  { "name": "Grace", "role": "Engineer", "department": "Frontend" }
]

29. SET

Update Bob’s age:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Bob"}) SET p.age = 26 RETURN p.name, p.age' --format rows

Output:

[
  { "name": "Bob", "age": 26 }
]

30. DELETE

Remove an isolated node (Frank has no connections):

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Frank"}) DELETE p' --format rows

Output:

[]

Note: DELETE without a RETURN clause produces an empty array ([]). The graph is modified in-memory for subsequent queries in the same session.

30b. DETACH DELETE

Remove a node and all its incident relationships:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"}) DETACH DELETE p MATCH (m:Person) RETURN m.name' --format rows

Output:

[
  { "name": "Bob" },
  { "name": "Charlie" },
  { "name": "Diana" },
  { "name": "Eve" },
  { "name": "Frank" }
]

Note: DETACH DELETE is useful when you want to remove a node without explicitly matching and deleting its relationships first.


CASE Expressions

31. General CASE with equality

Classify people by name:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, CASE WHEN p.name = "Alice" THEN "first" WHEN p.name = "Bob" THEN "second" ELSE "other" END AS position' --format rows

Output:

[
  { "name": "Alice", "position": "first" },
  { "name": "Bob", "position": "second" },
  { "name": "Charlie", "position": "other" },
  { "name": "Diana", "position": "other" },
  { "name": "Eve", "position": "other" },
  { "name": "Frank", "position": "other" }
]

32. General CASE with numeric comparison

Categorize by age using >= and <=:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, p.age, CASE WHEN p.age >= 35 THEN "senior" WHEN p.age >= 25 THEN "mid" ELSE "junior" END AS tier' --format rows

Output:

[
  { "name": "Alice", "age": 30, "tier": "mid" },
  { "name": "Bob", "age": 25, "tier": "mid" },
  { "name": "Charlie", "age": 35, "tier": "senior" },
  { "name": "Diana", "age": 40, "tier": "senior" },
  { "name": "Eve", "age": 28, "tier": "mid" },
  { "name": "Frank", "age": 32, "tier": "mid" }
]

33. Simple CASE

Map role values to short codes:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, CASE p.role WHEN "Engineer" THEN "eng" WHEN "Manager" THEN "mgmt" WHEN "Designer" THEN "des" ELSE "other" END AS dept' --format rows

Output:

[
  { "name": "Alice", "dept": "eng" },
  { "name": "Bob", "dept": "eng" },
  { "name": "Charlie", "dept": "des" },
  { "name": "Diana", "dept": "mgmt" },
  { "name": "Eve", "dept": "eng" },
  { "name": "Frank", "dept": "des" }
]

34. CASE with IS NULL

Handle missing properties:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, CASE WHEN p.email IS NULL THEN "no email" ELSE "has email" END AS status' --format rows

Output:

[
  { "name": "Alice", "status": "has email" },
  { "name": "Bob", "status": "no email" },
  { "name": "Charlie", "status": "has email" },
  { "name": "Diana", "status": "has email" },
  { "name": "Eve", "status": "no email" },
  { "name": "Frank", "status": "no email" }
]

35. CASE in ORDER BY

Sort by custom priority:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, p.role ORDER BY CASE p.role WHEN "Manager" THEN 0 WHEN "Engineer" THEN 1 WHEN "Designer" THEN 2 ELSE 3 END' --format rows

Output:

[
  { "name": "Diana", "role": "Manager" },
  { "name": "Alice", "role": "Engineer" },
  { "name": "Bob", "role": "Engineer" },
  { "name": "Eve", "role": "Engineer" },
  { "name": "Charlie", "role": "Designer" },
  { "name": "Frank", "role": "Designer" }
]

36. CASE with CONTAINS

Classify by department substring:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, p.department, CASE WHEN p.department CONTAINS "ack" THEN "infra" WHEN p.department CONTAINS "ront" THEN "client" ELSE "other" END AS category' --format rows

Output:

[
  { "name": "Alice", "department": "Backend", "category": "infra" },
  { "name": "Bob", "department": "Frontend", "category": "client" },
  { "name": "Charlie", "department": "Design", "category": "other" },
  { "name": "Diana", "department": "Backend", "category": "infra" },
  { "name": "Eve", "department": "Backend", "category": "infra" },
  { "name": "Frank", "department": "Design", "category": "other" }
]

37. Nested CASE

Combine conditions with nested CASE:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) RETURN p.name, CASE WHEN p.role = "Engineer" THEN CASE WHEN p.age >= 30 THEN "senior engineer" ELSE "junior engineer" END ELSE "not engineer" END AS title' --format rows

Output:

[
  { "name": "Alice", "title": "senior engineer" },
  { "name": "Bob", "title": "junior engineer" },
  { "name": "Charlie", "title": "not engineer" },
  { "name": "Diana", "title": "not engineer" },
  { "name": "Eve", "title": "junior engineer" },
  { "name": "Frank", "title": "not engineer" }
]

38. CASE in SET

Assign computed properties:

gcyphrq -g examples/team.json -e 'MATCH (p:Person) SET p.tier = CASE WHEN p.age >= 35 THEN "senior" WHEN p.age >= 25 THEN "mid" ELSE "junior" END RETURN p.name, p.tier' --format rows

Output:

[
  { "name": "Alice", "tier": "mid" },
  { "name": "Bob", "tier": "mid" },
  { "name": "Charlie", "tier": "senior" },
  { "name": "Diana", "tier": "senior" },
  { "name": "Eve", "tier": "mid" },
  { "name": "Frank", "tier": "mid" }
]

39. REMOVE

Remove a label or property from a node. The node and its relationships remain in the graph:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"}) REMOVE p:Person RETURN p.name AS name, p.label AS label' --format rows

Output:

[
  {
    "name": "Alice"
  }
]

(The label key is omitted entirely since undefined is not serializable to JSON.)

Property removal works the same way:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"}) REMOVE p.age RETURN p' --format rows

Multiple items can be combined:

gcyphrq -g examples/team.json -e 'MATCH (p:Person {name: "Alice"}) REMOVE p.age, p:Person RETURN p' --format rows

Next Steps