Cypher
Updated: May 22, 2026Categories: Query
Printed from:
Cypher Query Language (Neo4j) Cheatsheet
1. Connection and Basic Setup
Neo4j Browser
- Access via
http://localhost:7474/browser - Default credentials:
neo4j/neo4j(you are required to set a new password on first login)
Cypher-Shell
Bash
123456789# Connect to local database
cypher-shell -u neo4j -p password
# Connect to remote database
cypher-shell -a neo4j://hostname:7687 -u neo4j -p password
# Target a specific database (Neo4j 4+/5+)
cypher-shell -u neo4j -p password -d mydatabase
Language Drivers
Python
123456789101112131415# Python (neo4j official driver)
from neo4j import GraphDatabase
driver = GraphDatabase.driver(
"neo4j://localhost:7687",
auth=("neo4j", "password")
)
# Recommended: use execute_query for simple cases
records, summary, keys = driver.execute_query(
"MATCH (p:Person {name: $name}) RETURN p",
name="Alice",
database_="neo4j",
)
2. Graph Database Concepts
Core Elements
- Node: Entities in the graph (like People, Companies)
- Relationship: Directed, typed connections between nodes
- Property: Key-value attributes on nodes and relationships
- Label: Tag categorizing a node (a node may have multiple labels)
Basic Graph Structure
cypher
123456// Node with label and properties CREATE (:Person {name: 'Alice', age: 30}) // Relationship with type and properties CREATE ()-[:KNOWS {since: 2020}]->()
3. Basic Syntax and Patterns
Query Pattern Structure
cypher
1234MATCH (pattern) WHERE condition RETURN results
Cypher clauses can be chained with WITH to pipeline intermediate results, and a query without RETURN can be terminated with FINISH (Neo4j 5).
4. Creating Nodes and Relationships
CREATE
cypher
1234567891011121314// Create a single node CREATE (p:Person {name: 'John', age: 35}) // Create multiple nodes CREATE (p1:Person {name: 'Alice'}) CREATE (p2:Person {name: 'Bob'}) // Create a relationship between existing nodes MATCH (p1:Person {name: 'Alice'}), (p2:Person {name: 'Bob'}) CREATE (p1)-[:KNOWS]->(p2) // Create node with relationship in one command CREATE (p1:Person {name: 'Alice'})-[:WORKS_AT]->(c:Company {name: 'Tech Corp'})
MERGE (Create or Match)
cypher
12345678910// Create node if not exists, otherwise match MERGE (p:Person {name: 'John'}) ON CREATE SET p.created = timestamp() ON MATCH SET p.lastSeen = timestamp() // Merge with relationship MERGE (p:Person {name: 'Alice'}) MERGE (c:Company {name: 'Google'}) MERGE (p)-[:WORKS_AT]->(c)
5. Querying Patterns
Basic MATCH
cypher
1234567891011// Find all people MATCH (p:Person) RETURN p // Find people named John MATCH (p:Person {name: 'John'}) RETURN p // Complex pattern matching MATCH (p:Person)-[:KNOWS]->(friend:Person) WHERE p.name = 'Alice' RETURN friend.name
Label and Type Expressions (Neo4j 5)
cypher
12345678// Label disjunction / conjunction / negation MATCH (n:Person|Employee) RETURN n MATCH (n:Person&Employee) RETURN n MATCH (n:Person&!Contractor) RETURN n // Relationship type alternatives MATCH (a)-[:KNOWS|FOLLOWS]->(b) RETURN a, b
WHERE Clauses
cypher
123456789101112131415// Comparison operators MATCH (p:Person) WHERE p.age > 30 AND p.city = 'New York' RETURN p // Pattern-based conditions MATCH (p:Person)-[:WORKS_AT]->(c:Company) WHERE c.name STARTS WITH 'Tech' RETURN p, c // Pattern predicate (replaces the legacy EXISTS(pattern) function) MATCH (p:Person) WHERE EXISTS { (p)-[:WORKS_AT]->(:Company) } RETURN p
6. Updating Data
SET (Update Properties)
cypher
1234567MATCH (p:Person {name: 'John'}) SET p.age = 36 SET p += {email: 'john@example.com'} // Add a label SET p:Employee
REMOVE
cypher
123456MATCH (p:Person {name: 'John'}) REMOVE p.age // Remove a label REMOVE p:Employee
DELETE
cypher
12345678// Delete node (fails if it has relationships) MATCH (p:Person {name: 'John'}) DELETE p // Delete node and its relationships MATCH (p:Person {name: 'John'}) DETACH DELETE p
7. Path Finding and Traversal
Shortest Path
cypher
1234MATCH path = shortestPath((p1:Person)-[:KNOWS*]-(p2:Person)) WHERE p1.name = 'Alice' AND p2.name = 'Bob' RETURN path
Path with Length Constraints
cypher
1234MATCH path = (start:Person)-[:KNOWS*1..3]->(end:Person) WHERE start.name = 'Alice' RETURN path
Quantified Path Patterns (Neo4j 5)
cypher
1234567// Repeat a relationship pattern 1 to 3 times MATCH path = (start:Person) ((:Person)-[:KNOWS]->(:Person)){1,3} (end:Person) WHERE start.name = 'Alice' RETURN path
8. Aggregation Functions
cypher
123456789101112// Count connections MATCH (p:Person)-[:KNOWS]->(friend) RETURN p.name, count(friend) AS friendCount // Collect related nodes MATCH (p:Person)-[:WORKS_AT]->(c:Company) RETURN c.name, collect(p.name) AS employees // Sum numerical properties MATCH (p:Person) RETURN sum(p.salary) AS totalSalary
9. Conditional Logic
CASE Statement
cypher
12345678MATCH (p:Person) RETURN p.name, CASE WHEN p.age < 20 THEN 'Young' WHEN p.age < 40 THEN 'Middle-aged' ELSE 'Senior' END AS ageGroup
COALESCE and Property Existence
cypher
123456789// Use first non-null value RETURN coalesce(p.nickname, p.name) AS displayName // Check property existence (EXISTS(prop) is deprecated; // use IS NOT NULL instead) MATCH (p:Person) WHERE p.email IS NOT NULL RETURN p.name
10. Indexing and Constraints
The legacy CREATE INDEX ON :Label(prop) and CREATE CONSTRAINT ON ... ASSERT ... syntaxes are removed in Neo4j 5. Use the named form below.
Indexes
cypher
1234567891011121314151617181920212223// Range / B-tree index on a single property CREATE INDEX person_name_idx IF NOT EXISTS FOR (p:Person) ON (p.name) // Composite index CREATE INDEX person_name_age_idx IF NOT EXISTS FOR (p:Person) ON (p.name, p.age) // Text, point, and full-text indexes CREATE TEXT INDEX person_email_text IF NOT EXISTS FOR (p:Person) ON (p.email) CREATE FULLTEXT INDEX person_search IF NOT EXISTS FOR (p:Person) ON EACH [p.name, p.bio] // Vector index for embeddings (Neo4j 5) CREATE VECTOR INDEX person_embedding IF NOT EXISTS FOR (p:Person) ON (p.embedding) OPTIONS { indexConfig: { `vector.dimensions`: 1536, `vector.similarity_function`: 'cosine' } }
Constraints
cypher
123456789101112// Uniqueness CREATE CONSTRAINT person_email_unique IF NOT EXISTS FOR (p:Person) REQUIRE p.email IS UNIQUE // Property existence (Enterprise Edition) CREATE CONSTRAINT person_name_exists IF NOT EXISTS FOR (p:Person) REQUIRE p.name IS NOT NULL // Node key (Enterprise Edition) CREATE CONSTRAINT person_key IF NOT EXISTS FOR (p:Person) REQUIRE (p.firstName, p.lastName) IS NODE KEY
Inspection
cypher
123SHOW INDEXES SHOW CONSTRAINTS
11. Import and Export
CSV Import
cypher
123456789101112131415LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row CREATE (p:Person { name: row.name, age: toInteger(row.age) }) // Batch large loads with CALL { ... } IN TRANSACTIONS LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS row CALL { WITH row MERGE (p:Person {id: row.id}) SET p.name = row.name, p.age = toInteger(row.age) } IN TRANSACTIONS OF 10000 ROWS
Export to CSV
cypher
1234// Most exports are performed with cypher-shell or apoc.export.csv.* MATCH (p:Person) RETURN p.name AS Name, p.age AS Age
12. Performance Optimization
Best Practices
- Create indexes on frequently queried properties
- Limit result set size with
LIMIT - Avoid unbounded variable-length path traversals
- Use
PROFILE(execution + db hits) orEXPLAIN(plan only) to analyze queries - Prefer parameters over string concatenation so plans can be cached
cypher
1234// Analyze query performance PROFILE MATCH (p:Person {name: $name}) RETURN p
13. Common Graph Patterns
Recommendation Engine
cypher
123456// Find friends of friends not yet connected MATCH (p:Person {name: 'Alice'})-[:KNOWS]->(friend)-[:KNOWS]->(recommendation) WHERE NOT (p)-[:KNOWS]->(recommendation) AND p <> recommendation RETURN DISTINCT recommendation
Network Analysis
cypher
123456// Find most connected individuals MATCH (p:Person)-[:KNOWS]-(friend) RETURN p.name, count(DISTINCT friend) AS connectionCount ORDER BY connectionCount DESC LIMIT 10
Subqueries
cypher
123456789// CALL { ... } subquery for per-row work MATCH (p:Person) CALL { WITH p MATCH (p)-[:WORKS_AT]->(c:Company) RETURN collect(c.name) AS companies } RETURN p.name, companies
14. Best Practices for Graph Modeling
- Keep labels specific and meaningful
- Use relationships to represent distinct interactions
- Avoid using relationships for data that can be properties
- Model data based on query patterns
- Be consistent with naming conventions (e.g.
PascalCaselabels,UPPER_SNAKE_CASErelationship types,camelCaseproperties) - Use constraints to maintain data integrity and to back uniqueness lookups with an index
Anti-Patterns to Avoid
- Overly generic relationship types (e.g.
HAS,RELATED_TO) - Storing redundant information across nodes
- Ignoring performance implications of unbounded paths
- Not leveraging graph-specific querying (joins-by-id instead of traversal)
Additional Resources
Continue Learning
Discover more cheatsheets to boost your productivity