Skip to content

Cypher Syntax Guide

Cypher is currently the most popular, de facto standard query language for graph databases (originally invented by Neo4j and later open-sourced as OpenCypher). It is a declarative language whose greatest feature is its ASCII-art inspired visual text symbols for expressing graph patterns.

This document provides detailed instructions on Cypher's basic syntax, keywords, and core operations supported by GoGraph, along with code examples.


1. Syntax Structure and Core Expressions

Cypher uses very intuitive symbols to depict "nodes" and "relationships":

1.1 Nodes

Use parentheses () to represent nodes (like a circle). - (): Anonymous node. - (n): Binds the node to variable n for later reference. - (n:User): A node with the :User label. - (n:User {name: 'Alice', age: 30}): A node with properties.

1.2 Relationships

Use square brackets [] to represent relationships, combined with dashes and arrows --> , <--, -- to indicate direction. - -->: Represents an outgoing relationship pointing to the right. - -[r]->: Binds the relationship to variable r. - -[r:KNOWS]->: Specifies the relationship type as :KNOWS. - -[r:KNOWS {since: 2022}]->: A relationship with properties.

1.3 Path Patterns

Combine nodes and relationships to form complete query paths: (a:User)-[:KNOWS]->(b:User)-[:PURCHASED]->(p:Product)


2. Data Operations (CRUD Operation Examples)

2.1 Creating Data (CREATE)

CREATE is used to insert new nodes, labels, properties, and relationships into the graph.

Creating a single node:

CREATE (n:Person {name: 'Alice', age: 30})

Creating a graph (nodes+relationships) in one go:

CREATE (a:Person {name: 'Alice'}),
       (b:Person {name: 'Bob'}),
       (a)-[:KNOWS {since: 2020}]->(b)

2.2 Querying Data (MATCH & RETURN)

MATCH is used to declare the graph pattern you are looking for. It is typically used together with WHERE (conditions) and RETURN (results).

Query all nodes belonging to Person:

MATCH (n:Person)
RETURN n

Conditional filtering and property return:

MATCH (n:Person)
WHERE n.age >= 18
RETURN n.name, n.age

Traversal relationship query:

MATCH (a:Person {name: 'Alice'})-[r:KNOWS]->(b:Person)
RETURN b.name, r.since

2.3 Updating Data (SET)

SET is specifically used to update or add node properties, or overwrite labels.

Updating a specific node's properties:

MATCH (n:Person {name: 'Alice'})
SET n.age = 31
Note: In GoGraph, if node n previously did not have an age property, this is a new addition; if it already existed, this is an overwrite modification.

2.4 Deleting Data (DELETE / REMOVE)

DELETE is used to delete entities (nodes and relationships) from the graph. Deleting a specific node and all its associated relationships:

MATCH (n:Person {name: 'Alice'})
DETACH DELETE n
(Note: If without DETACH and the node still has relationships, deletion may fail or be in an undefined state)

REMOVE is used to remove specific labels or properties from a node, without deleting the node itself. Removing a node's labels and properties:

MATCH (n:Person {name: 'Bob'})
REMOVE n:VIP, n.age


3. Expressions and Functions

In clauses like WHERE and SET, Cypher supports various expressions.

3.1 Comparison Operators

Supports standard =, !=, >, >=, <, <= comparison operations.

MATCH (n:Product) WHERE n.price <= 99.9 RETURN n

3.2 Parameterized Queries (Parameterization)

To prevent injection attacks and improve query engine cache hit rates, it is recommended to use $ to declare parameters:

// Query statement
MATCH (n:User) WHERE n.age > $minAge RETURN n.name

// Map passed during API execution:
// {"minAge": 18}
In GoGraph's latest architecture, the execution engine supports dynamically parsing parameter dictionaries and mapping them to graph comparison logic.


4. Indexes and Constraints

In most graph databases, establishing indexes can greatly improve query speed. - Implicit Index Mechanism: In GoGraph's current implementation, when you CREATE (n:User), the system underlying engine automatically maintains label (Label) inverted indexes and property (Property) indexes for you. - Index Scan Trigger Condition: When you execute MATCH (n:User), the underlying engine automatically captures label constraints and performs O(K) complexity index scans instead of O(N) full table traversal.


5. Transaction Processing

Each Cypher execution statement runs in an implicit atomic transaction by default. However, in practical engineering, you may need to combine multiple Cypher statements into one large transaction:

// Controlling transactions in a Go application:
tx, _ := db.BeginTx(ctx, nil)

// Execute the first step
tx.Exec("CREATE (n:Account {id: 1, balance: 100})")

// Execute the second step; if business failure occurs, you can Rollback()
tx.Exec("MATCH (n:Account {id: 1}) SET n.balance = 50")

// Final commit
tx.Commit()

6. Usage Notes

  1. Relationship direction cannot be ambiguous: In CREATE statements, relationships must have a clear arrow direction (such as ->). In MATCH, you can omit the arrow to ignore direction (GoGraph engine currently prioritizes exact direction matching).
  2. Beware of Cartesian products: If not bridged through relationships, using multiple disconnected patterns MATCH (a:Person), (b:Company) may cause results to grow exponentially.
  3. Prioritize explicit Labels: In large datasets, executing MATCH (n) RETURN n will slow down the entire database system. You should use label constraints MATCH (n:SpecificLabel) as much as possible to trigger graph indexes.