目标:掌握 Cypher 的基本语法规则,能独立完成 “创建 - 查询 - 更新 - 删除”(CRUD)操作,理解图数据的表达逻辑。
1. 先搞懂 3 个核心语法符号(基础中的基础)
Cypher 语法高度可视化,记住这 3 个符号就能描述任何图结构:
| 符号 | 含义 | 示例 |
|---|---|---|
() |
节点(可加标签 / 属性) | (u:User)(标签:User)、(p:Product {name:"手机"})(带属性) |
-[:类型]-> |
有向关系(可加属性) | -[:FRIENDS_WITH]->(类型:FRIENDS_WITH)、-[:PURCHASED {time:"2025-11-18"}]->(带属性) |
[] |
关系变量(用于引用) | -[r:PURCHASED]->(用 r 指代该关系,后续可查询 / 更新 r 的属性) |
步骤 1:创建节点(用户、商品)
// 创建3个用户节点(标签:User,带id/name/age属性)
CREATE (u1:User {id:1, name:"张三", age:28, city:"北京"}),(u2:User {id:2, name:"李四", age:30, city:"上海"}),(u3:User {id:3, name:"王五", age:25, city:"广州"});// 创建2个商品节点(标签:Product,带id/name/price/category属性)
CREATE (p1:Product {id:101, name:"iPhone 15", price:7999, category:"手机"}),(p2:Product {id:102, name:"华为Mate 60", price:6999, category:"手机"}),(p3:Product {id:103, name:"AirPods Pro", price:1999, category:"配件"});
Cypher
CREATE 语法中,u1、u2、u3 是 节点变量(Node Variables),它们的核心区别和作用如下:一、本质区别:指向不同的节点实例
u1、u2、u3 是三个独立的变量名,分别对应你创建的 3 个 User 节点:u1→ 指向{id:1, name:"张三", ...}的 User 节点u2→ 指向{id:2, name:"李四", ...}的 User 节点u3→ 指向{id:3, name:"王五", ...}的 User 节点
变量名本身可以任意定义(比如改成
zhangsan、lisi、wangwu),但必须唯一(同一语句中不能重复用同一个变量指向不同节点)。二、核心作用:临时引用节点,方便后续操作
变量的核心价值是「在当前 Cypher 语句中临时引用节点」,避免重复写匹配条件。具体有两个常见场景:
1. 同一 CREATE 语句中创建关联关系(简化语法)
如果创建节点的同时要创建节点间的关系,变量可以直接关联,无需额外
MATCH:// 创建3个用户节点(u1/u2/u3),同时创建张三和李四的好友关系
CREATE (u1:User {id:1, name:"张三"}),(u2:User {id:2, name:"李四"}),(u3:User {id:3, name:"王五"}),(u1)-[:FRIENDS_WITH]->(u2); // 直接用u1/u2引用节点,创建关系
如果没有变量,你需要先
CREATE 节点,再 MATCH 节点才能创建关系,步骤更繁琐。2. 后续语句中匹配 / 操作指定节点
如果后续要对某个节点单独操作(比如修改属性、创建关系、删除),可以通过变量快速定位(仅限同一语句上下文):
// 创建节点后,立即给u1(张三)添加一个新属性
CREATE (u1:User {id:1, name:"张三"}),(u2:User {id:2, name:"李四"}),(u3:User {id:3, name:"王五"})
SET u1.email = "zhangsan@xxx.com"; // 用u1直接定位张三,添加属性
三、关键注意点
- 变量仅在当前语句有效:
u1、u2、u3只在你写的这个CREATE语句中起作用,语句执行结束后,变量会失效。如果之后要操作这些节点,需要通过MATCH (u:User {id:1})重新匹配(不能直接用u1)。 - 变量名不影响节点本身:节点的本质是「标签(User)+ 属性(id/name/age 等)」,变量名只是临时引用,哪怕把
u1改成x,节点的内容(属性、标签)完全不变。 - 变量可省略(但不推荐):如果创建节点后不需要立即操作,也可以省略变量:
但这种写法后续无法在同一语句中创建关系,灵活性差,所以一般都会定义变量
// 省略变量,仅创建节点(无法直接关联关系) CREATE (:User {id:1, name:"张三"}),(:User {id:2, name:"李四"}),(:User {id:3, name:"王五"});
步骤 2:创建关系(好友、购买)
// 1. 创建好友关系(张三↔李四,张三→王五)
MATCH (u1:User {id:1}), (u2:User {id:2})
CREATE (u1)-[:FRIENDS_WITH {since:2020, status:"close"}]->(u2),(u2)-[:FRIENDS_WITH {since:2020, status:"close"}]->(u1); // 双向关系需单独创建MATCH (u1:User {id:1}), (u3:User {id:3})
CREATE (u1)-[:FRIENDS_WITH {since:2022, status:"ordinary"}]->(u3);// 2. 创建购买关系(张三买了iPhone 15,李四买了华为Mate 60和AirPods)
MATCH (u1:User {id:1}), (p1:Product {id:101})
CREATE (u1)-[:PURCHASED {time:"2025-01-10", amount:1}]->(p1);MATCH (u2:User {id:2}), (p2:Product {id:102}), (p3:Product {id:103})
CREATE (u2)-[:PURCHASED {time:"2025-03-15", amount:1}]->(p2),(u2)-[:PURCHASED {time:"2025-03-15", amount:1}]->(p3);
步骤 3:查询练习(从简单到复杂)
// 1. 基础查询:查询所有用户的姓名和年龄
MATCH (u:User) RETURN u.name AS 用户名, u.age AS 年龄;// 2. 条件查询:查询年龄>25的用户
MATCH (u:User) WHERE u.age > 25 RETURN u.name, u.age;// 3. 关系查询:查询“购买了手机的用户”
MATCH (u:User)-[r:PURCHASED]->(p:Product {category:"手机"})
RETURN u.name AS 用户名, r.time AS 购买时间, p.name AS 商品名;// 4. 关联查询:查询“张三的朋友购买了什么商品”(1度关联)
MATCH (z:User {name:"张三"})-[:FRIENDS_WITH]->(f:User)-[r:PURCHASED]->(p:Product)
RETURN z.name AS 本人, f.name AS 朋友, p.name AS 朋友购买的商品;// 5. 多深度查询:查询“张三的1-2度朋友”(直接朋友+朋友的朋友)
MATCH (z:User {name:"张三"})-[:FRIENDS_WITH*1..2]->(f:User)
RETURN z.name, f.name, length(relationships(p)) AS 关系深度; // length()计算路径长度// 6. 聚合查询:统计每个商品的购买次数
MATCH (u:User)-[r:PURCHASED]->(p:Product)
RETURN p.name AS 商品名, sum(r.amount) AS 总销量
ORDER BY 总销量 DESC;
步骤 4:更新与删除练习
// 1. 更新:给张三增加“职业”属性,修改年龄为29
MATCH (u:User {name:"张三"})
SET u.job = "工程师", u.age = 29
RETURN u;// 2. 更新关系:修改李四购买华为Mate 60的数量为2
MATCH (u:User {name:"李四"})-[r:PURCHASED]->(p:Product {name:"华为Mate 60"})
SET r.amount = 2
RETURN r;// 3. 删除:删除王五的所有关系和王五节点
MATCH (u:User {name:"王五"})-[r]->() // 匹配王五的所有关系
DELETE r, u; // 先删关系,再删节点// 4. 删除属性:删除张三的“city”属性
MATCH (u:User {name:"张三"})
REMOVE u.city
RETURN u;
二、进阶阶段:掌握高频场景语法
入门后,重点攻克 Cypher 的 “高级特性”,覆盖实际开发中的高频场景:
1. 索引与约束(性能优化核心)
当数据量较大(万级 +)时,必须通过索引加速查询,约束保证数据一致性:
// 1. 创建索引:对User的name属性创建索引(高频查询字段)
CREATE INDEX idx_user_name ON :User(name);// 2. 创建唯一约束:保证User的id属性不重复(类似主键)
CREATE CONSTRAINT unique_user_id ON :User(id) ASSERT id IS UNIQUE;// 3. 查看索引/约束
SHOW INDEXES;
SHOW CONSTRAINTS;// 4. 删除索引/约束
DROP INDEX idx_user_name;
DROP CONSTRAINT unique_user_id;
2. 路径操作与函数
Cypher 内置大量函数,简化路径分析、属性处理等操作:
// 1. 路径函数:获取路径中的所有节点/关系
MATCH p = (u:User)-[:PURCHASED]->(p:Product)
RETURN nodes(p) AS 路径节点, relationships(p) AS 路径关系;// 2. 最短路径查询(内置算法)
MATCH shortestPath(p = (u1:User {name:"张三"})-[*]->(u2:User {name:"李四"}))
RETURN p, length(p) AS 最短路径长度;// 3. 字符串函数:模糊查询(类似SQL的LIKE)
MATCH (p:Product) WHERE p.name CONTAINS "手机" // 包含“手机”
RETURN p.name;// 4. 聚合函数:统计、分组
MATCH (u:User)-[r:PURCHASED]->(p:Product)
GROUP BY p.category // 按商品分类分组
RETURN p.category AS 分类, count(u) AS 购买人数, sum(r.amount) AS 总销量;
3. 批量操作(高效处理大量数据)
实际项目中常需批量导入 / 更新数据,避免逐条执行:
// 1. 批量创建:通过UNWIND遍历列表批量创建节点
WITH ["赵六", "孙七", "周八"] AS names // 定义姓名列表
UNWIND names AS name // 遍历列表,每个name对应一条记录
CREATE (u:User {name: name, age: 26, city: "深圳"});// 2. 批量更新:给所有手机类商品降价1000
MATCH (p:Product {category:"手机"})
SET p.price = p.price - 1000
RETURN p.name, p.price;
4. 条件分支(CASE 语句)
类似 SQL 的 CASE,支持复杂逻辑判断:
// 根据商品价格分类
MATCH (p:Product)
RETURN p.name AS 商品名,CASEWHEN p.price > 5000 THEN "高端产品"WHEN p.price > 2000 THEN "中端产品"ELSE "低端产品"END AS 价格等级;