跳转至

Cypher 查询语言语法说明

Cypher 是目前最流行、事实上的图数据库标准查询语言(最初由 Neo4j 发明,后开源为 OpenCypher)。它是一种声明式语言,最大的特色是其受 ASCII-art 启发,用可视化的文本符号来表达图的模式(Pattern)。

本文档将详细说明 Cypher 的基础语法、关键字及 GoGraph 支持的核心操作,并提供代码示例。


1. 语法结构与核心表达 (Syntax & Structure)

Cypher 使用非常直观的符号来描绘“节点”与“关系”:

1.1 节点 (Nodes)

使用圆括号 () 来表示节点(就像一个圆圈)。 - ():匿名节点。 - (n):将节点绑定到变量 n,后续可引用。 - (n:User):带有 :User 标签的节点。 - (n:User {name: 'Alice', age: 30}):带有属性的节点。

1.2 关系 (Relationships)

使用方括号 [] 表示关系,配合破折号和箭头 --><---- 来表示方向。 - -->:表示指向右侧的外向关系。 - -[r]->:将关系绑定到变量 r。 - -[r:KNOWS]->:指定关系的类型为 :KNOWS。 - -[r:KNOWS {since: 2022}]->:带有属性的关系。

1.3 模式路径 (Path Patterns)

将节点和关系组合在一起,构成完整的查询路径: (a:User)-[:KNOWS]->(b:User)-[:PURCHASED]->(p:Product)


2. 数据操作 (CRUD 操作示例)

2.1 创建数据 (CREATE)

CREATE 用于向图库中插入新的节点、标签、属性和关系。

创建单个节点:

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

一次性创建图谱(节点+关系):

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

2.2 查询数据 (MATCH & RETURN)

MATCH 用于声明你要寻找的图模式。它通常与 WHERE(条件)和 RETURN(返回)连用。

查询所有属于 Person 的节点:

MATCH (n:Person)
RETURN n

条件过滤与属性返回:

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

遍历关系查询:

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

2.3 更新数据 (SET)

SET 专门用于更新、新增节点的属性或覆盖标签。

修改特定节点的属性:

MATCH (n:Person {name: 'Alice'})
SET n.age = 31
注意:在 GoGraph 中,如果 n 之前没有 age 属性,则为新增;如果已有,则为覆盖修改。

2.4 删除数据 (DELETE / REMOVE)

DELETE 用于删除图中的实体(节点和关系)。 删除特定节点及与之相关的全部关系:

MATCH (n:Person {name: 'Alice'})
DETACH DELETE n
(注:如果不带 DETACH 且该节点还有关系,删除可能会失败或处于未定义状态)

REMOVE 用于移除节点的特定标签或属性,而不删除节点本身。 移除节点的标签和属性:

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


3. 表达式与函数 (Expressions)

WHERESET 等子句中,Cypher 支持多种表达式。

3.1 比较运算符

支持标准的 =!=>>=<<= 比较操作。

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

3.2 参数化查询 (Parameterization)

为了防止注入攻击提高查询引擎的缓存命中率,推荐使用 $ 声明参数:

// 查询语句
MATCH (n:User) WHERE n.age > $minAge RETURN n.name

// 通过 API 执行时传入的 Map:
// {"minAge": 18}
在 GoGraph 的最新架构中,执行引擎支持动态解析参数字典并映射至图比较逻辑。


4. 索引与约束 (Indexes)

在大多数图数据库中,建立索引能极大提升查询速度。 - 隐式索引机制:在 GoGraph 的当前实现中,当您 CREATE (n:User) 时,系统底层引擎会自动为您维护标签(Label)倒排索引和属性(Property)索引。 - Index Scan 触发条件:当您执行 MATCH (n:User) 时,底层引擎会自动捕获标签约束,走 O(K) 复杂度的索引扫描,而非 O(N) 的全表逐个遍历。


5. 事务处理 (Transactions)

Cypher 的每一条执行语句默认都运行在一个隐式原子事务中。 但在实际工程中,您可能需要将多个 Cypher 组合在一个大事务中:

// 在 Go 应用程序中控制事务:
tx, _ := db.BeginTx(ctx, nil)

// 执行第一步
tx.Exec("CREATE (n:Account {id: 1, balance: 100})")

// 执行第二步,如果发生业务失败可以 Rollback()
tx.Exec("MATCH (n:Account {id: 1}) SET n.balance = 50")

// 最终提交
tx.Commit()

6. 使用注意事项 (Usage Notes)

  1. 关系方向不能含糊:在 CREATE 语句中,关系必须具备明确的箭头指向(如 ->)。而在 MATCH 中,您可以省略箭头表示忽略方向(GoGraph 引擎目前优先遵循精确的方向匹配)。
  2. 警惕笛卡尔积:如果没有通过关系进行桥接,使用多个断开的模式 MATCH (a:Person), (b:Company) 可能会导致返回的结果成倍数爆炸。
  3. 优先明确 Label:在大型数据集中,执行 MATCH (n) RETURN n 会拖慢整个数据库系统,应该尽可能使用标签约束 MATCH (n:SpecificLabel) 来触发图索引。