OpenCypher Complete Syntax Quick Reference¶
Note: This quick reference is organized by CRUD operations, covering all core syntax, rules, functions, and examples of OpenCypher. It can be copied and saved as a .txt or .md file for convenient offline reference.
1. Basic Syntax Rules¶
1. Case Sensitivity and Identifiers¶
-
Keywords: Case-insensitive (MATCH / match / Match are equivalent)
-
Identifiers: Variables, labels, relationship types, and property names are case-sensitive (e.g., :Person and :person are two different labels)
-
Naming rules: Must start with a letter or underscore, can contain letters, numbers, underscores, $, and #
-
Core reserved words: MATCH, WHERE, RETURN, CREATE, DELETE, SET, WITH, UNWIND, UNION, MERGE, REMOVE
2. Comment Syntax¶
-
Single-line comments: // comment content (example: // Match all user nodes)
-
Multi-line comments: /* comment content / (example: / Batch create nodes and relationships for data initialization */)
3. Data Types¶
| Type Category | Specific Types | Description | Examples |
|---|---|---|---|
| Scalar Types (Basic) | INTEGER | Positive and negative integers, no length limit | 10, -5, 100000 |
| FLOAT | Decimal numbers | 3.14, -0.5, 10.0 | |
| BOOLEAN | Logical values, only two possible values | true, false | |
| STRING | Text content, single or double quotes both work | "Alice", 'TechCorp' | |
| NULL | Empty value, represents no data | p.age IS NULL | |
| Temporal Types | DATE | Date only, format yyyy-MM-dd | date(), date("2026-03-28") |
| DATETIME | Date and time with timezone | datetime(), datetime("2026-03-28T10:30:00") | |
| TIME | Time only, with timezone | time(), time("10:30:00") | |
| LOCALDATETIME | Date and time without timezone | localdatetime("2026-03-28T10:30:00") | |
| LOCALTIME | Time without timezone | localtime("10:30:00") | |
| DURATION | Time interval | duration({days:1, hours:2}) | |
| Composite Types | LIST | Ordered, repeatable collection | [1,2,3], ["Alice","Bob"] |
| MAP | Key-value pair collection, keys are strings | {name: "Alice", age: 30} |
2. Core Graph Element Syntax (Basic)¶
1. Nodes¶
Syntax format: (variable:label1:label2 {propertyKey1: propertyValue1, propertyKey2: propertyValue2})
Note: Variable, labels, and properties are all optional. Multiple labels are separated by colons. Properties are a key-value pair collection.
// 1. Empty node (no variable, no label, no properties)
()
// 2. Node with variable (variable used for later reference)
(n)
// 3. Node with single label (label used for classification)
(:Person)
// 4. Node with multiple labels
(:Person:Employee:Manager)
// 5. Complete node (variable + label + properties)
(p:Person {name: "Alice", age: 30, city: "Beijing", email: "alice@example.com"})
2. Relationships¶
Syntax format: -[variable:relationshipType {propertyKey: propertyValue}]->
Note: Direction is optional (-> outgoing, <-- incoming, -- undirected), variable is optional, relationship type is required (only single type), properties are optional
// 1. Undirected relationship (no variable, no type, no properties)
--
// 2. Directed relationship (outgoing)
->
// 3. Directed relationship (incoming)
<--
// 4. Relationship with type (core required)
-[:FRIENDS_WITH]->
// 5. Relationship with variable (variable used for later reference)
-[r]->
// 6. Complete relationship (variable + type + properties)
-[r:FRIENDS_WITH {since: 2020, status: "close"}]->
3. Patterns¶
Note: A combination of nodes and relationships, used to describe graph structure, is the core of clauses like MATCH and CREATE
// 1. Simple path (two nodes + one relationship)
(a:Person)-[:FRIENDS_WITH]->(b:Person)
// 2. Variable-length path (1 to 5 relationships, range can be adjusted)
(a:Person)-[:KNOWS*1..5]->(b:Person)
// 3. Arbitrary-length path (no upper limit, use with caution to avoid performance issues)
(a:Person)-[:FOLLOWS*]->(b:Person)
// 4. Multiple pattern matching (multiple independent nodes/paths)
(a:Person), (b:Company), (a)-[:WORKS_FOR]->(b)
// 5. Path variable (saves complete path for later operations)
path = (a)-[:KNOWS]->(b)-[:FRIENDS_WITH]->(c)
3. CRUD Core Operation Syntax (Key Points)¶
(1) Read: Querying Data¶
1. MATCH: Pattern Matching (Core Query Clause)¶
Purpose: Find nodes, relationships, or paths that match the specified pattern in the graph
// Example 1: Match all Person nodes
MATCH (p:Person)
// Example 2: Match Person nodes and their friend relationships
MATCH (a:Person)-[:FRIENDS_WITH]->(b:Person)
// Example 3: Match path and save as variable
MATCH path = (a:Person)-[:KNOWS*1..3]->(b:Person)
// Example 4: Match multiple patterns (Person and Company nodes, plus employment relationship)
MATCH (p:Person), (c:Company), (p)-[:WORKS_FOR]->(c)
2. WHERE: Conditional Filtering¶
Purpose: Filter results from MATCH or WITH, supports multiple condition combinations
// Example 1: Basic conditions (age greater than 18, city is Beijing)
MATCH (p:Person)
WHERE p.age > 18 AND p.city = "Beijing"
RETURN p.name
// Example 2: String matching (name contains "Li")
MATCH (p:Person)
WHERE p.name CONTAINS "Li" // Contains (case-insensitive)
// WHERE p.name STARTS WITH "A" // Starts with A
// WHERE p.name ENDS WITH "e" // Ends with e
RETURN p.name
// Example 3: List matching (city in specified list)
MATCH (p:Person)
WHERE p.city IN ["Beijing", "Shanghai", "Guangzhou"]
RETURN p.name, p.city
// Example 4: Property existence (has email property)
MATCH (p:Person)
WHERE EXISTS(p.email)
RETURN p.name, p.email
// Example 5: NULL value check
MATCH (p:Person)
WHERE p.age IS NOT NULL
RETURN p.name, p.age
3. RETURN: Return Results¶
Purpose: Specify what data to return from the query, is the terminating clause, supports aliases, aggregation, and DISTINCT
// Example 1: Return specified properties of nodes
MATCH (p:Person)
WHERE p.age > 18
RETURN p.name, p.age, p.city
// Example 2: Return with aliases (simplify output)
MATCH (p:Person)
RETURN p.name AS userName, p.age AS userAge
// Example 3: Aggregate queries (count, average, etc.)
MATCH (p:Person)
RETURN COUNT(p) AS totalPerson, // Total count
AVG(p.age) AS avgAge, // Average age
MIN(p.age) AS minAge, // Minimum age
MAX(p.age) AS maxAge // Maximum age
// Example 4: DISTINCT return (avoid duplicate results)
MATCH (p:Person)-[:WORKS_FOR]->(c:Company)
RETURN DISTINCT c.name AS companyName // Return distinct company names
// Example 5: Return path-related information
MATCH path = (a:Person)-[:FRIENDS_WITH]->(b:Person)
RETURN nodes(path) AS allNodes, // All nodes in the path
relationships(path) AS allRels, // All relationships in the path
length(path) AS pathLength // Path length (number of relationships)
4. WITH: Intermediate Result Passing¶
Purpose: Process intermediate results and pass them to subsequent clauses (similar to SQL's HAVING, can be used for post-aggregation filtering)
// Example: Query users with more than 5 friends
MATCH (p:Person)-[:FRIENDS_WITH]->(f:Person)
WITH p, COUNT(f) AS friendCount // Intermediate result: user and their friend count
WHERE friendCount > 5 // Filter users with more than 5 friends
RETURN p.name, friendCount // Return final results
5. UNWIND: Unfold Lists¶
Purpose: Expand a list into multiple rows for easier subsequent processing (often used for batch operations)
// Example 1: Unfold a simple list
UNWIND [1, 2, 3, 4, 5] AS num
RETURN num * 2 AS doubleNum // Output each number doubled
// Example 2: Unfold node property list
MATCH (p:Person {name: "Alice"})
UNWIND p.hobbies AS hobby // Assuming p.hobbies is a list ["reading", "travel"]
RETURN p.name, hobby
6. ORDER BY / LIMIT / SKIP: Sorting and Pagination¶
Purpose: Sort returned results, limit quantity, skip specified rows (used for paginated queries)
// Example: Paginated query (skip first 10, take 5, sorted by age descending, name ascending)
MATCH (p:Person)
RETURN p.name, p.age
ORDER BY p.age DESC, p.name ASC // First by age descending, then by name ascending
SKIP 10 // Skip first 10
LIMIT 5 // Take 5 results
7. UNION / UNION ALL: Result Combination¶
Purpose: Combine results from multiple queries. UNION removes duplicates, UNION ALL keeps duplicates (both queries must return the same number of columns and compatible types)
// Example 1: UNION (deduplicated combination)
MATCH (p:Person) RETURN p.name AS name
UNION
MATCH (c:Company) RETURN c.name AS name
// Example 2: UNION ALL (keep duplicates, better performance)
MATCH (p:Person {city: "Beijing"}) RETURN p.name AS name
UNION ALL
MATCH (p:Person {city: "Shanghai"}) RETURN p.name AS name
(2) Create: Inserting Data¶
1. CREATE: Direct Creation¶
Purpose: Create nodes, relationships, or combinations of nodes and relationships (creates new data each time, even if duplicated)
// Example 1: Create a single node
CREATE (p:Person {name: "Bob", age: 28, city: "Shanghai"})
// Example 2: Create multiple nodes (separated by commas)
CREATE (p1:Person {name: "Charlie"}), (c:Company {name: "TechCorp", address: "Beijing"})
// Example 3: Create node + relationship (create associated data at once)
CREATE (a:Person {name: "Dave"})-[:WORKS_FOR {since: 2022, position: "Engineer"}]->(c:Company {name: "TechCorp"})
// Example 4: Create node with multiple labels
CREATE (p:Person:Student {name: "Eve", age: 20, school: "Beijing University"})
2. MERGE: Match or Create¶
Purpose: Ensure the specified pattern exists—if it exists, match it; if not, create it (avoids duplicate creation, commonly used)
// Example 1: Match or create node
MERGE (p:Person {name: "Dave"}) // If a Person node with name=Dave exists, match it; otherwise create
ON CREATE SET p.createdAt = timestamp() // Only executes on creation: set creation timestamp
ON MATCH SET p.updatedAt = timestamp() // Only executes on match: update timestamp
// Example 2: Match or create node + relationship
MATCH (a:Person {name: "Alice"}), (b:Person {name: "Bob"})
MERGE (a)-[:FRIENDS_WITH]->(b) // If the relationship exists, match; otherwise create
ON CREATE SET a.friendCount = COALESCE(a.friendCount, 0) + 1 // On relationship creation, update friend count
(3) Update: Modifying Data¶
1. SET: Add/Modify Properties, Labels¶
Purpose: Add new properties to nodes/relationships, modify existing properties, or add labels to nodes
// Example 1: Modify a single property
MATCH (p:Person {name: "Alice"})
SET p.age = 31 // Modify age
// Example 2: Modify multiple properties
MATCH (p:Person {name: "Alice"})
SET p.city = "Shanghai", p.email = "alice_new@example.com"
// Example 3: Batch set properties (using MAP for simplification)
MATCH (p:Person {name: "Alice"})
SET p += {phone: "123456789", gender: "female"} // Batch add/modify properties
// Example 4: Add a label to a node
MATCH (p:Person {name: "Alice"})
SET p:Employee // Add Employee label to Alice node
2. REMOVE: Delete Properties, Labels¶
Purpose: Delete properties from nodes/relationships, or delete labels from nodes (cannot delete relationship types)
// Example 1: Delete a single property
MATCH (p:Person {name: "Alice"})
REMOVE p.phone // Delete phone property
// Example 2: Delete multiple properties (separated by commas)
MATCH (p:Person {name: "Alice"})
REMOVE p.phone, p.gender
// Example 3: Delete a label from a node
MATCH (p:Person {name: "Alice"})
REMOVE p:Employee // Remove Employee label from Alice node
(4) Delete: Deleting Data¶
Note: Before deleting a node, you must first delete all relationships of that node (otherwise an error occurs); DETACH DELETE can cascade delete the node and all its relationships
// Example 1: Delete a relationship (first match the relationship, then delete)
MATCH (a:Person {name: "Alice"})-[r:FRIENDS_WITH]->(b:Person {name: "Bob"})
DELETE r // Delete this friendship
// Example 2: Delete a node (must delete relationships first, otherwise error)
MATCH (p:Person {name: "Dave"})
MATCH (p)-[r]->() // Match all outgoing relationships of p
DELETE r, p // Delete relationships first, then delete node
// Example 3: Cascade delete (recommended, automatically deletes node and all relationships)
MATCH (p:Person {name: "Dave"})
DETACH DELETE p // Delete node and all associated relationships at once
// Example 4: Delete all matching nodes and relationships
MATCH (p:Person)-[r:WORKS_FOR]->(c:Company {name: "OldCorp"})
DETACH DELETE p, r, c // Delete user, employment relationship, and company node
4. Functions and Expressions (Common)¶
1. Aggregate Functions (Used in RETURN / WITH aggregate queries)¶
-
COUNT(expression): Count quantity (COUNT(*) counts all rows, COUNT(p) counts non-null nodes)
-
SUM(expression): Sum (only applicable to numeric types)
-
AVG(expression): Average (only applicable to numeric types)
-
MIN(expression): Minimum value
-
MAX(expression): Maximum value
-
COLLECT(expression): Collect results into a list
// Example: Aggregate function usage
MATCH (p:Person)-[:WORKS_FOR]->(c:Company)
RETURN c.name AS company,
COUNT(p) AS employeeCount, // Number of employees at the company
AVG(p.age) AS avgEmployeeAge, // Average employee age
COLLECT(p.name) AS employeeNames // List of employee names
2. Scalar Functions (Process single values)¶
(1) Mathematical Functions¶
abs(-5) → 5 // Absolute value
ceil(3.14) → 4 // Round up
floor(3.99) → 3 // Round down
round(3.5) → 4 // Round to nearest
rand() → 0.123... // Generate random number between 0 and 1
(2) String Functions¶
length("Alice") → 5 // String length
toUpper("Alice") → "ALICE" // Convert to uppercase
toLower("ALICE") → "alice" // Convert to lowercase
replace("Alice", "A", "B") → "Blice" // Replace string
substring("Alice", 1, 3) → "lic" // Extract substring (start index, length)
(3) Temporal Functions¶
date() → date("2026-03-28") // Current date
datetime() → datetime("2026-03-28T10:30:00") // Current datetime
timestamp() → 1711585800000 // Current timestamp (milliseconds)
duration({days:1, hours:2}) → duration({days:1, hours:2}) // Duration
(4) Graph-Related Functions¶
id(p) → 123 // Unique ID of node/relationship
labels(p) → ["Person", "Employee"] // All labels of a node
type(r) → "FRIENDS_WITH" // Type of relationship
properties(p) → {name: "Alice", age: 30} // All properties of node/relationship
3. List Functions (Process lists)¶
head([1,2,3]) → 1 // First element of list
last([1,2,3]) → 3 // Last element of list
tail([1,2,3]) → [2,3] // List without first element
range(1,5) → [1,2,3,4,5] // Generate list with specified range
reverse([1,2,3]) → [3,2,1] // Reverse list
size([1,2,3]) → 3 // List length
4. CASE Expressions (Conditional Logic)¶
Purpose: Similar to if-else in programming languages, used to return different values based on conditions
MATCH (p:Person)
RETURN p.name,
CASE
WHEN p.age < 18 THEN 'Minor' // Age < 18: Minor
WHEN p.age >= 18 AND p.age < 60 THEN 'Adult' // 18 ≤ Age < 60: Adult
ELSE 'Elderly' // Otherwise: Elderly
END AS ageGroup
5. Advanced Features¶
1. Pattern Comprehension¶
Purpose: Directly collect pattern matching results into a list, simplifying queries
// Example: Query each user's friend name list
MATCH (p:Person)
RETURN p.name,
// Pattern comprehension: match p's friends, collect friend names into a list
[p_friend IN [(p)-[:FRIENDS_WITH]->(f) | f.name] | p_friend] AS friendNames
2. Indexes and Constraints (Optimize Performance, Ensure Data Integrity)¶
// (1) Create index (used to speed up queries, based on label + property)
CREATE INDEX FOR (p:Person) ON (p.name) // Create index on name property for Person label
CREATE INDEX FOR (c:Company) ON (c.address) // Create index on address property for Company label
// (2) Create unique constraint (ensures property values are unique, prevents duplicates)
CREATE CONSTRAINT ON (p:Person) ASSERT p.email IS UNIQUE // Person's email must be unique
CREATE CONSTRAINT ON (c:Company) ASSERT c.name IS UNIQUE // Company's name must be unique
// (3) Delete index
DROP INDEX FOR (p:Person) ON (p.name)
// (4) Delete constraint
DROP CONSTRAINT ON (p:Person) ASSERT p.email IS UNIQUE
3. Transaction Control (Optional, not supported by all databases)¶
// Begin transaction
BEGIN TRANSACTION
// Execute operations (create, modify, delete, etc.)
CREATE (p:Person {name: "Frank"})
MATCH (p:Person {name: "Frank"}) SET p.age = 35
// Commit transaction (confirm changes)
COMMIT
// Rollback transaction (cancel changes)
ROLLBACK
6. Complete Query Examples (Comprehensive Application)¶
// Example: Query friends of users over 30 in Beijing, and the companies where those friends work, paginated return
MATCH (p:Person)-[:FRIENDS_WITH]->(f:Person)-[:WORKS_FOR]->(c:Company)
// Conditions: user age > 30, city is Beijing
WHERE p.age > 30 AND p.city = "Beijing"
// Intermediate results: user, friend info, company info, collect friends and company list
WITH p, COLLECT({friendName: f.name, companyName: c.name, position: f.position}) AS friendsCompanyInfo
// Sort by user name ascending, skip first 5, take 10
ORDER BY p.name ASC
SKIP 5 LIMIT 10
// Return final results
RETURN p.name AS userName,
p.age AS userAge,
friendsCompanyInfo AS friendsAndCompanies
7. Common Notes and Considerations¶
-
Relationship types only support a single type; specifying multiple types simultaneously (such as
-[:FRIENDS_WITH:COLLEAGUE]->) is invalid -
Variable-length path queries (
*) should be used with caution, especially unbounded paths (such as-[:KNOWS*]->), as they can severely impact query performance -
When deleting a node, you must first delete all its relationships, or use DETACH DELETE for cascade deletion
-
UNION requires both queries to return exactly the same number of columns with matching data types, otherwise an error occurs
-
Indexes are only effective for label + property queries in MATCH and WHERE clauses; creating indexes reasonably can greatly improve query performance