MATCH, WHERE and RETURN

Neo4j · Essentials · 12 min

Pattern matching is the core of Cypher; nearly every query starts with MATCH.

MATCH finds all places in the graph where a pattern fits, binding variables for each match. RETURN says what to output.

MATCH (p:Person)-[:FOLLOWS]->(other:Person)
WHERE p.born < 1995
RETURN p.name, other.name
ORDER BY p.name
LIMIT 10

Things to know:

  • Properties in the pattern, (p:Person {name: 'Ann'}), are shorthand for equality conditions in WHERE.
  • WHERE supports comparisons, AND/OR/NOT, IN [...], STARTS WITH, CONTAINS, =~ regex and IS NULL. Missing properties are null.
  • Leaving out the arrowhead, -[:FOLLOWS]-, matches either direction.
  • RETURN can output nodes, relationships, properties, expressions and maps; AS renames columns and DISTINCT removes duplicates.
  • ORDER BY, SKIP and LIMIT work like in SQL.

If a pattern matches nothing, the query returns no rows. Each MATCH row is one way the pattern fits, so a person following three people appears in three rows.

Always include labels in patterns: MATCH (n {name: 'Ann'}) without a label has to check every node in the database.

Example

// who does each person follow, oldest followers first
MATCH (p:Person)-[f:FOLLOWS]->(other:Person)
WHERE f.since >= 2021
RETURN p.name AS follower, other.name AS follows, f.since AS since
ORDER BY p.born, since;
// follower | follows | since
// "Ann"    | "Bob"   | 2021
// "Ann"    | "Cy"    | 2024
// "Cy"     | "Bob"   | 2023

// either direction: everyone connected to Bob by FOLLOWS
MATCH (:Person {name: 'Bob'})-[:FOLLOWS]-(x:Person)
RETURN collect(x.name) AS connected;   // ["Ann", "Cy"] (order may vary)

Remember

  • MATCH binds variables for every place a pattern fits
  • WHERE filters; inline {k: v} is shorthand for equality
  • Omit the arrowhead to match both directions
  • Always use labels so the planner can avoid scanning all nodes

Watch out for

  • Omitting labels in MATCH, forcing a scan of every node.

Check yourself

  1. Ann follows Bob and Cy. How many rows does MATCH (a:Person {name:'Ann'})-[:FOLLOWS]->(x) RETURN a.name return?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: neo4j.com/docs/cypher-manual/current/clauses/match/