Neo4j 图数据库核心操作详解
Neo4j 是一种基于图模型的数据库,其主要结构由节点和关系构成,使用专为图数据设计的查询语言 Cypher(类似于 SQL)。本文将系统介绍 Cypher 语言中的增删改查操作,并涵盖节点、关系及属性的完整应用场景。
()
一、基础元素说明
节点
在 Neo4j 中,节点是图的基本单位,通常用于表示实体。节点可以拥有标签(类似关系型数据库中的表名)以及一系列属性(以键值对形式存储)。例如:
(u:User {name: "张三", age: 25})
关系
关系连接两个节点,具有方向性,可用箭头表示:
-- 或 -[r:REL_TYPE]->
其中
-> 表示关系的方向。关系也可以带有类型和属性,如:
(u)-[f:FRIENDS_WITH {since: 2020}]->(v)
属性类型支持
节点与关系均可设置属性,支持的数据类型包括字符串、数字、布尔值、列表、日期等,示例如下:
{tags: ["技术", "旅行"], birth: date("1998-01-01")}
二、核心操作:增删改查
1. 数据新增(CREATE)
用于创建新的节点或建立节点之间的关系,支持单条或多条批量插入。
(1) 创建单个带标签和属性的节点
// 创建一个 "User" 标签的节点,包含 name 和 age 属性
CREATE (u:User {name: "张三", age: 25, gender: "男", isActive: true})
RETURN u; // RETURN 用于返回创建的结果(可选)
(2) 批量创建多个节点
// 批量创建 3 个 User 节点,用逗号分隔
CREATE (u1:User {name: "李四", age: 28}),
(u2:User {name: "王五", age: 23}),
(p:Product {name: "Neo4j 实战", price: 89.9})
RETURN u1, u2, p;
(3) 创建节点并关联已有节点(先匹配后连接)
通过
MATCH 匹配已存在的节点,再创建新关系,避免重复生成节点:
// 1. 先确保节点存在(如果不存在可先用 CREATE 或 MERGE)
MATCH (u:User {name: "张三"}), (p:Product {name: "Neo4j 实战"})
// 2. 创建 "购买" 关系,带属性
CREATE (u)-[b:BUY {time: date(), amount: 1}]->(p)
RETURN u, b, p; // 返回完整的图结构
(4) 链式创建多个相互关联的节点
// 创建 3 个节点 + 2 个关系(张三 -> 李四 是朋友,李四 -> 王五 是同事)
CREATE (u1:User {name: "张三"})-[f:FRIENDS]->(u2:User {name: "李四"})-[c:COLLEAGUE]->(u3:User {name: "王五"})
RETURN u1, f, u2, c, u3;
2. 数据查询(MATCH + RETURN)
利用
MATCH 子句匹配所需的节点或关系结构,结合 RETURN 返回结果集,支持条件筛选、排序与分页功能。
(1) 查询图中所有节点
// 查询所有节点(无过滤,适合小数据量)
MATCH (n) RETURN n;
// 查询所有 User 标签的节点
MATCH (u:User) RETURN u.name, u.age; // 只返回指定属性(避免返回全部)
(2) 条件查询(使用 WHERE 子句)
// 查询年龄 > 25 的 User,返回姓名和年龄,按年龄降序排序
MATCH (u:User)
WHERE u.age > 25 AND u.gender = "男"
RETURN u.name AS 姓名, u.age AS 年龄 // 给属性起别名
ORDER BY u.age DESC
LIMIT 10; // 分页(前 10 条)
(3) 查询包含节点及其关系的图结构
// 查询 "张三" 购买的所有商品(返回用户、购买关系、商品)
MATCH (u:User {name: "张三"})-[b:BUY]->(p:Product)
WHERE b.time >= date("2024-01-01") // 过滤关系属性
RETURN u.name, b.time, p.name, p.price;
// 查询 "张三" 的朋友的朋友(2 度关系)
MATCH (u:User {name: "张三"})-[f:FRIENDS]->()-[:FRIENDS]->(friendOfFriend)
RETURN friendOfFriend.name;
(4) 聚合统计查询(如 COUNT、SUM 等)
// 统计 User 节点总数
MATCH (u:User) RETURN COUNT(u) AS userCount;
// 统计每个用户的购买次数和总消费金额
MATCH (u:User)-[b:BUY]->(p:Product)
RETURN u.name, COUNT(b) AS buyTimes, SUM(p.price * b.amount) AS totalCost
GROUP BY u.name; // 按用户分组
3. 数据修改(SET 操作)
使用
SET 修改节点或关系的属性,可添加新属性或更新已有字段,通常配合 MATCH 定位目标对象。
(1) 更新节点属性
// 更新 "张三" 的年龄和新增邮箱属性
MATCH (u:User {name: "张三"})
SET u.age = 26, u.email = "zhangsan@xxx.com" // 多个属性用逗号分隔
RETURN u;
// 给节点添加新标签(一个节点可多个标签)
MATCH (u:User {name: "张三"})
SET u:VIPUser // 新增 VIPUser 标签
RETURN labels(u); // 返回节点的所有标签(结果:["User", "VIPUser"])
(2) 修改关系上的属性信息
// 更新 "张三" 购买 "Neo4j 实战" 的订单状态
MATCH (u:User {name: "张三"})-[b:BUY]->(p:Product {name: "Neo4j 实战"})
SET b.status = "已发货"
RETURN b;
(3) 删除特定属性(使用 REMOVE)
// 删除 "张三" 的 gender 属性
MATCH (u:User {name: "张三"})
REMOVE u.gender
RETURN u;
// 删除节点的 VIPUser 标签
MATCH (u:User {name: "张三"})
REMOVE u:VIPUser
RETURN labels(u); // 结果:["User"]
4. 数据删除(DELETE)
使用
DELETE 删除节点或关系。注意:删除节点前必须清除其所有关联的关系,否则会引发错误。
(1) 删除指定关系
// 删除 "张三" 和 "Neo4j 实战" 之间的 BUY 关系
MATCH (u:User {name: "张三"})-[b:BUY]->(p:Product {name: "Neo4j 实战"})
DELETE b; // 只删除关系,节点保留
(2) 删除节点(需先解除关联关系)
// 方法 1:先删关系,再删节点(分步)
MATCH (u:User {name: "王五"})-[r]->() // 匹配王五的所有出关系
DELETE r; // 先删关系
MATCH (u:User {name: "王五"})
DELETE u; // 再删节点
// 方法 2:同时删除节点和其所有关联关系(推荐)
MATCH (u:User {name: "王五"})-[r]-() // 匹配所有关联关系(无方向)
DELETE u, r; // 同时删除节点和关系
(3) 清空整个数据库中的所有节点和关系(谨慎操作!)
MATCH (n)-[r]->()
DELETE n, r; // 先删所有关系和节点
// 或简化(Neo4j 支持)
MATCH (n)
DETACH DELETE n; // DETACH 自动删除节点的所有关联关系,再删节点
三、关键补充:MERGE 操作
MERGE 的作用类似于“存在则匹配,不存在则创建”,常用于防止重复插入唯一性数据,如用户记录或特定关系。
CREATE + MATCH
典型用法如下:
// 确保存在 name 为 "赵六" 的 User 节点,不存在则创建
MERGE (u:User {name: "赵六"})
ON CREATE SET u.age = 30, u.gender = "男" // 不存在时执行(创建后设置属性)
ON MATCH SET u.age = u.age + 1 // 存在时执行(年龄+1)
RETURN u;
// 确保 "赵六" 和 "张三" 之间存在 FRIENDS 关系,不存在则创建
MATCH (u:User {name: "赵六"}), (v:User {name: "张三"})
MERGE (u)-[f:FRIENDS]->(v)
ON CREATE SET f.since = date()
RETURN u, f, v;
四、实用技巧汇总
- 查看当前数据库中的节点标签:
MATCH (n) RETURN DISTINCT labels(n); - 查看已存在的关系类型:
MATCH ()-[r]->() RETURN DISTINCT type(r); - 执行模糊查询(字符串模式匹配):
MATCH (u:User) WHERE u.name STARTS WITH "张" // 以"张"开头 // 或 WHERE u.name CONTAINS "三" // 包含"三" RETURN u.name; - 处理列表类型的属性操作:
// 给节点添加列表属性 MATCH (u:User {name: "张三"}) SET u.hobbies = ["篮球", "编程"] RETURN u; // 向列表添加元素(不重复) MATCH (u:User {name: "张三"}) SET u.hobbies = u.hobbies + ["旅行"] // 直接添加(允许重复) // 或 SET u.hobbies = apoc.coll.union(u.hobbies, ["旅行"]) // 去重添加(需安装 APOC 插件) RETURN u;
五、使用注意事项
- 关系必须连接两个有效节点,不允许孤立的关系存在。
- 删除节点时,应先移除其所有关联关系;可通过
简化此过程。DETACH DELETE - 属性名称不应包含空格或特殊字符,推荐采用小驼峰命名法,例如
。userName - 面对大规模数据查询时,建议对高频检索字段建立索引(如 User 节点的 name 字段):
CREATE INDEX idx_user_name FOR (u:User) ON (u.name); // 创建索引
DROP INDEX idx_user_name; // 删除索引
在实际开发中,推荐结合 Neo4j Browser 可视化工具来执行 Cypher 语句,能够直观展示图谱结构与查询结果,提升调试效率。


雷达卡


京公网安备 11010802022788号







