Neo4j’s Cypher Quick Start
Cypher is Neo4j’s declarative graph query language. This Quick Start page provide infomation that you need to get started quering or adding data to a Knowledge Graph.
Table of Contents:
Cypher Syntax Guide
Basic Syntax
Cypher uses ASCII art to represent graph patterns:
()represents nodes[]represents relationships-->shows relationship direction
Creating Data
Create a node:
CREATE (p:Person {name: 'Alice', age: 30})
Create a relationship:
MATCH (a:Person {name: 'Alice'})
MATCH (b:Person {name: 'Bob'})
CREATE (a)-[:KNOWS]->(b)
Create everything at once:
CREATE (a:Person {name: 'Alice'})-[:KNOWS]->(b:Person {name: 'Bob'})
Reading Data
Find all nodes with a label:
MATCH (p:Person)
RETURN p
Find specific nodes:
MATCH (p:Person {name: 'Alice'})
RETURN p
Find relationships:
MATCH (a:Person)-[r:KNOWS]->(b:Person)
RETURN a.name, b.name
Pattern matching with depth:
MATCH (a:Person {name: 'Alice'})-[:KNOWS*1..3]->(friend)
RETURN friend.name
Filtering with WHERE
MATCH (p:Person)
WHERE p.age > 25
RETURN p.name, p.age
Updating Data
Update properties:
MATCH (p:Person {name: 'Alice'})
SET p.age = 31
Add labels:
MATCH (p:Person {name: 'Alice'})
SET p:Developer
Deleting Data
Delete relationships:
MATCH (a:Person)-[r:KNOWS]->(b:Person)
DELETE r
Delete nodes (must delete relationships first):
MATCH (p:Person {name: 'Alice'})
DETACH DELETE p // DETACH deletes relationships too
Common Clauses
MATCH- find patternsCREATE- create nodes/relationshipsRETURN- specify what to outputWHERE- filter resultsSET- update propertiesDELETE- remove dataORDER BY- sort resultsLIMIT- restrict number of results
Quick Tips
- Use
RETURN *to see all matched variables - Always create indexes for frequently queried properties
- Use
EXPLAINorPROFILEbefore queries to optimize performance - Node labels use PascalCase, relationship types use UPPER_CASE
Questions & Answers
Is ‘p’ in “MATCH (p:Person {name: ‘Alice’}) RETURN p” just an alias?
Yes, exactly! p is a variable (or alias) that represents the matched node. You can think of it like a variable in programming. When you write:
MATCH (p:Person {name: 'Alice'})
RETURN p
The p is just a name you’re giving to the node that matches the pattern. You could use any valid identifier:
MATCH (person:Person {name: 'Alice'})
RETURN person
MATCH (x:Person {name: 'Alice'})
RETURN x
MATCH (alice:Person {name: 'Alice'})
RETURN alice
All of these do the same thing. The variable lets you:
- Reference the node later in the same query:
MATCH (p:Person {name: 'Alice'}) SET p.age = 31 RETURN p - Access its properties:
MATCH (p:Person {name: 'Alice'}) RETURN p.name, p.age - Use it in relationship patterns:
MATCH (p:Person {name: 'Alice'})-[:KNOWS]->(friend) RETURN p, friend
In “MATCH (p:Person {name: ‘Alice’})” can I use a wildcard to match several name?
Yes! You can use wildcards, but not directly in the curly braces {}. You need to use the WHERE clause with string matching operators.
Using Wildcards
Starts with:
MATCH (p:Person)
WHERE p.name STARTS WITH 'Ali'
RETURN p
Ends with:
MATCH (p:Person)
WHERE p.name ENDS WITH 'ice'
RETURN p
Contains:
MATCH (p:Person)
WHERE p.name CONTAINS 'lic'
RETURN p
Regular Expressions
For more complex patterns, use regex with =~:
MATCH (p:Person)
WHERE p.name =~ 'Ali.*'
RETURN p
MATCH (p:Person)
WHERE p.name =~ '(?i)alice' // case-insensitive
RETURN p
Why Not in Curly Braces?
The {name: 'Alice'} syntax is for exact matches only. It’s actually shorthand for:
MATCH (p:Person)
WHERE p.name = 'Alice'
RETURN p
For any pattern matching or wildcards, you need the full WHERE clause with the appropriate string operators.
Note: These string operations are case-sensitive by default. Use (?i) in regex or convert to lowercase for case-insensitive matching:
MATCH (p:Person)
WHERE toLower(p.name) CONTAINS 'alice'
RETURN p
Query didn’t return any data - how to troublkeshoot?
Let’s troubleshoot why a query returns no results. Here are the most common causes:
1. Check if the Label Exists
First, verify that you have nodes with the Entity label:
MATCH (e:Entity)
RETURN count(e)
If this returns 0, you don’t have any Entity nodes.
2. Check Property Names
The property might be named differently. See what properties exist:
MATCH (e:Entity)
RETURN e LIMIT 5
Or list all property keys:
MATCH (e:Entity)
RETURN keys(e)
LIMIT 10
3. Check Property Values
See what values entity_type actually has:
MATCH (e:Entity)
RETURN DISTINCT e.entity_type
Maybe it’s:
'author'(lowercase)'AUTHOR'(uppercase)- Stored differently altogether
4. Case-Sensitive Match
If the value is lowercase, try:
MATCH (e:Entity)
WHERE toLower(e.entity_type) = 'author'
RETURN e LIMIT 25
5. Check All Your Data
See what labels and nodes you actually have:
CALL db.labels()
MATCH (n)
RETURN labels(n), count(n)
Try these diagnostic queries - they will help identify exactly where the mismatch is.
Explain query: MATCH (a:Person {name: ‘Alice’})-[:KNOWS*1..3]->(friend) RETURN friend.name
Query syntax breakdown:
MATCH (a:Person {name: 'Alice'})-[:KNOWS*1..3]->(friend)
RETURN friend.name
Let’s break this down piece by piece:
(a:Person {name: 'Alice'})- Find a node labeledPersonwith name ‘Alice’, call ita-[:KNOWS*1..3]->- FollowKNOWSrelationships, with variable length:*1..3means “1 to 3 hops away”*1would be direct friends only*2would be friends-of-friends only*1..3captures friends, friends-of-friends, and friends-of-friends-of-friends->indicates direction (outgoing from Alice)
(friend)- The destination nodes at the end of these paths, calledfriendRETURN friend.name- Return the names of all these people
Example:
Alice -KNOWS-> Bob -KNOWS-> Carol -KNOWS-> David
This query would return: Bob (1 hop), Carol (2 hops), David (3 hops)
If you want unlimited depth, use * without numbers: -[:KNOWS*]-> (but be careful - this can be slow on large graphs!)
What is the rule for using single quote ‘value’ vs. double “value” in property values?
In Cypher (Neo4j), you MUST use single quotes for string values:
✅ MATCH (p:Person {name: 'Alice'})
❌ MATCH (p:Person {name: "Alice"})
Double quotes are for identifiers (property names, labels, variables) that contain special characters or spaces:
// Normal identifier - no quotes needed
MATCH (p:Person)
RETURN p.name
// Identifier with spaces - needs double quotes
MATCH (p:Person)
RETURN p.`first name` // or p."first name"
// Label with special characters
MATCH (p:`Special-Label`)
RETURN p
The Rule:
- Single quotes
'...'→ String values/literals - Double quotes
"..."or backticks`...`→ Identifiers with special characters - No quotes → Normal identifiers (labels, properties, variables)
This is different from some SQL databases where both can be used for strings, so it’s easy to mix up!
What relationship’s directions are supported in MATCH?
You have three options for direction:
// Directed: left to right (outgoing)
MATCH (p:Person)-[r:KNOWS]->(f:Friend)
// Directed: right to left (incoming)
MATCH (p:Person)<-[r:KNOWS]-(f:Friend)
// Undirected: either direction
MATCH (p:Person)-[r:KNOWS]-(f:Friend)
The arrow > or < determines direction, not left-right position!
Example:
// Find people Alice knows
MATCH (a:Person {name: 'Alice'})-[:KNOWS]->(friend)
// Find people who know Alice
MATCH (a:Person {name: 'Alice'})<-[:KNOWS]-(friend)
Can I use multiple predicates sequentially?
Absolutely! You can chain patterns together:
MATCH (p:Person)-[:KNOWS]->(f:Friend)-[:WORKS_AT]->(o:Organization {name: 'Anthropic'})
RETURN p, f, o
This finds: Person → knows → Friend → works at → Anthropic
You can chain as many as you need:
MATCH (p:Person)-[:KNOWS]->(f)-[:LIVES_IN]->(c:City)-[:LOCATED_IN]->(country:Country)
RETURN p.name, country.name
Can I combine several predicates with AND or OR in MATCH?
You cannot use AND/OR directly in the MATCH pattern, but you use multiple MATCH clauses or WHERE:
Option A: Multiple MATCH clauses (implicit AND)
MATCH (p:Person)-[:KNOWS]->(alice:Person {name: 'Alice'})
MATCH (p)-[:WORKS_AT]->(o:Organization {name: 'Google'})
RETURN p
Option B: Single MATCH with WHERE (AND)
MATCH (p:Person)-[:KNOWS]->(alice:Person),
(p)-[:WORKS_AT]->(o:Organization)
WHERE alice.name = 'Alice' AND o.name = 'Google'
RETURN p
Option C: OR conditions
MATCH (p:Person)-[:KNOWS]->(friend:Person)
WHERE friend.name = 'Alice' OR friend.name = 'Bob'
RETURN p
Option D: Complex conditions
MATCH (p:Person)-[:KNOWS]->(friend),
(p)-[:WORKS_AT]->(org)
WHERE (friend.name = 'Alice' OR friend.name = 'Bob')
AND org.name = 'Google'
AND p.age > 25
RETURN p
Key point: The comma , in MATCH acts as AND - both patterns must match the same starting node(s).