Skip to content

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
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