Real graph questions span several hops, and these patterns are what make Cypher more expressive than joins.
Patterns can be chained to any length: (a)-[:FOLLOWS]->(b)-[:WORKS_AT]->(c:Company) reads "a follows b who works at c". Reusing a variable creates a join point: in MATCH (a)-[:FOLLOWS]->(b), (b)-[:FOLLOWS]->(a) the same a and b must satisfy both patterns, which finds mutual follows.
Within a single MATCH, Cypher never uses the same relationship twice in one match (relationship isomorphism), but the same node can appear more than once. That matters for "friend of a friend" queries, where the start person can show up as their own friend-of-friend; filter with WHERE fof <> me.
OPTIONAL MATCH works like a left outer join: if the pattern is not found, the variables are null instead of the row disappearing.
MATCH (p:Person)
OPTIONAL MATCH (p)-[:WORKS_AT]->(c:Company)
RETURN p.name, c.namereturns every person, with null for those without a company.
Comma-separated patterns that share no variables produce a cartesian product of their matches, which is almost always a mistake and can be huge; Neo4j warns about it.
Example
// recommend people to Ann: followed by people she follows, not yet followed
MATCH (me:Person {name: 'Ann'})-[:FOLLOWS]->(:Person)-[:FOLLOWS]->(fof:Person)
WHERE fof <> me AND NOT (me)-[:FOLLOWS]->(fof)
RETURN fof.name AS suggestion, count(*) AS via
ORDER BY via DESC;
// everyone, with their employer if any
MATCH (p:Person)
OPTIONAL MATCH (p)-[:WORKS_AT]->(c:Company)
RETURN p.name, c.name AS company;
// "Ann" null | "Bob" "Acme" | "Cy" nullRemember
- Chain hops in one pattern; shared variables join patterns
- One match never reuses a relationship, but can revisit a node
- OPTIONAL MATCH yields nulls instead of dropping rows
- Unconnected comma patterns create cartesian products
Watch out for
- Forgetting
WHERE fof <> meand recommending people to themselves.