neo4j入门

docker安装

1
mkdir -p ~/neo4j/{data,logs,plugins,conf}

~/neo4j目录下创建docker-compose.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
version: '3.8'
services:
neo4j:
# 指定Neo4j镜像,:latest为最新版,也可指定具体版本如4.4.19、5.18.0
image: neo4j:latest
# 容器名,自定义
container_name: neo4j
# 开机自启
restart: always
# 端口映射:宿主端口:容器端口(核心端口,不要随意改)
ports:
- "7474:7474" # Neo4j 浏览器Web界面端口
- "7687:7687" # Neo4j Bolt协议端口(程序连接用,如Java/Python客户端)
- "7473:7473" # HTTPS协议的Web界面端口(可选,一般不用)
# 环境变量配置(核心:设置初始密码、允许远程连接)
environment:
- NEO4J_AUTH=neo4j/123456 # 初始账号/密码:neo4j是固定用户名,密码自定义(如123456)
- NEO4J_server_memory_heap_initial__size=512m # 堆内存初始值,根据服务器配置调整
- NEO4J_server_memory_heap_max__size=2G # 堆内存最大值
- NEO4J_server_memory_pagecache_size=1G # 页缓存大小
# 数据卷挂载:本地目录映射到容器内,实现持久化
volumes:
- ~/neo4j/data:/data
- ~/neo4j/logs:/logs
- ~/neo4j/plugins:/plugins
- ~/neo4j/conf:/conf
# 资源限制(可选,根据服务器配置调整)
deploy:
resources:
limits:
cpus: '1'
memory: 4G
1
docker compose up -d

访问

http://127.0.0.1:7474

输入刚刚配置的用户名密码。

以例子来学习命令

例子概述

以学生、课程、老师为节点;选课、授课、任教为关系。

1. 节点类型(Label)& 属性

  • Student(学生):id (学号)、name (姓名)、age (年龄)、gender (性别)
  • Course(课程):id (课程号)、name (课程名)、credit (学分)、type (课程类型:必修 / 选修)
  • Teacher(老师):id (工号)、name (姓名)、subject (授课科目)、age (年龄)

2. 关系类型(Relationship)& 属性

  • STUDY(选课):Student → Course,属性:score (成绩)、semester (学期)
  • TEACH(授课):Teacher → Course,属性:teach_year (授课年份)
  • WORK_AT(任教):Teacher → (可选,无属性,指向学校,简化为固定值)

命令

一、基础操作:创建节点(CREATE / MERGE)

创建节点是图数据库的基础,推荐MERGE(不存在则创建,存在则匹配,避免重复),新手也可先学CREATE(直接创建,会重复)。

1. 单节点创建(CREATE)

1
2
3
4
5
6
7
8
9
10
11
// 创建1个学生节点
CREATE (s:Student {id: 202401, name: "张三", age: 20, gender: "男"})
RETURN s; // RETURN 用于返回创建的节点,可省略

// 创建1个课程节点
CREATE (c:Course {id: "C001", name: "Python基础", credit: 3, type: "必修"})
RETURN c;

// 创建1个老师节点
CREATE (t:Teacher {id: "T001", name: "李老师", subject: "计算机", age: 35})
RETURN t;

2.批量创建节点(CREATE 多个)

1
2
3
4
5
6
7
8
9
// 批量创建2个学生、2个课程、2个老师
CREATE
(s2:Student {id: 202402, name: "李四", age: 19, gender: "女"}),
(s3:Student {id: 202403, name: "王五", age: 20, gender: "男"}),
(c2:Course {id: "C002", name: "图数据库", credit: 2, type: "选修"}),
(c3:Course {id: "C003", name: "Java开发", credit: 3, type: "必修"}),
(t2:Teacher {id: "T002", name: "王老师", subject: "数学", age: 40}),
(t3:Teacher {id: "T003", name: "张老师", subject: "计算机", age: 32})
RETURN s2, s3, c2, c3, t2, t3;

3.防重复创建(MERGE 推荐)

1
2
3
4
// 若学号202401的学生不存在则创建,存在则直接匹配
MERGE (s:Student {id: 202401})
ON CREATE SET s.name = "张三", s.age = 20, s.gender = "男"
RETURN s;

ON CREATE SET:仅在节点创建时设置属性,避免覆盖已有数据。

二、核心操作:创建节点间的关系(CREATE / MERGE)

关系是图数据库的灵魂,格式为 (节点1)-[关系名:关系类型 {属性}]->(节点2),箭头表示关系方向。

1. 先匹配节点,再创建关系(推荐,避免创建无效关系)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// 1. 张三(202401)选了Python基础(C001),成绩90,2024秋学期
MATCH (s:Student {id: 202401}), (c:Course {id: "C001"})
CREATE (s)-[r:STUDY {score: 90, semester: "2024秋"}]->(c)
RETURN s, r, c;

// 2. 李老师(T001)讲授Python基础(C001),2024年授课
MATCH (t:Teacher {id: "T001"}), (c:Course {id: "C001"})
CREATE (t)-[r:TEACH {teach_year: 2024}]->(c)
RETURN t, r, c;

// 3. 批量创建关系(李四/王五选课,张老师授课)
MATCH
(s2:Student {id: 202402}), (s3:Student {id: 202403}),
(c1:Course {id: "C001"}), (c2:Course {id: "C002"}),
(t3:Teacher {id: "T003"})
CREATE
(s2)-[:STUDY {score: 85, semester: "2024秋"}]->(c1),
(s2)-[:STUDY {score: 92, semester: "2024秋"}]->(c2),
(s3)-[:STUDY {score: 78, semester: "2024秋"}]->(c1),
(t3)-[:TEACH {teach_year: 2024}]->(c2),
(t3)-[:TEACH {teach_year: 2024}]->(c3),
(t1:Teacher {id: "T001"})-[:WORK_AT]->({name: "XX大学"}) // 直接创建带关系的匿名节点(学校)
RETURN *; // RETURN * 返回所有匹配/创建的节点和关系

2.防重复关系(MERGE 关系)

1
2
3
4
5
// 避免张三重复创建选C001的关系
MATCH (s:Student {id: 202401}), (c:Course {id: "C001"})
MERGE (s)-[r:STUDY {semester: "2024秋"}]->(c)
ON CREATE SET r.score = 90 // 仅创建时设成绩
RETURN s, r, c;

三、查询操作:MATCH (最常用,覆盖单节点 / 关系 / 多条件 / 聚合)

查询是 Cypher 的核心,MATCH 用于匹配节点 / 关系,搭配WHERE筛选、RETURN返回、ORDER BY排序、LIMIT限制结果,新手重点掌握。

1. 简单查询:匹配所有 / 指定类型节点

1
2
3
4
5
6
7
8
9
10
// 1. 查询所有节点(新手调试用,生产环境避免)
MATCH (n) RETURN n LIMIT 10; // LIMIT 限制返回10个,防止数据过多

// 2. 查询所有学生节点,返回姓名和年龄(指定属性,更简洁)
MATCH (s:Student) RETURN s.name, s.age;

// 3. 查询所有必修课程,按学分降序
MATCH (c:Course {type: "必修"})
RETURN c.name, c.credit
ORDER BY c.credit DESC;

2.带关系的查询:匹配节点 + 关系(核心)

1
2
3
4
5
6
7
8
9
10
11
12
13
// 1. 查询张三选了哪些课程,返回课程名和成绩
MATCH (s:Student {name: "张三"})-[r:STUDY]->(c:Course)
RETURN s.name, c.name, r.score;

// 2. 查询谁教了Python基础(反向查询,箭头可省略)
MATCH (t:Teacher)-[r:TEACH]->(c:Course {name: "Python基础"})
RETURN t.name, r.teach_year;

// 3. 查询选了Python基础的所有学生姓名和成绩,按成绩升序
MATCH (s:Student)-[r:STUDY]->(c:Course {name: "Python基础"})
RETURN s.name, r.score
ORDER BY r.score ASC
LIMIT 5;

3.多条件筛选:WHERE 子句(复杂条件用,比直接写属性更灵活)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 1. 查询年龄≥20的男学生,选了学分≥3的课程
MATCH (s:Student)-[r:STUDY]->(c:Course)
WHERE s.age >= 20 AND s.gender = "男" AND c.credit >=3
RETURN s.name, c.name, r.score;

// 2. 查询成绩在80~90之间的选课记录
MATCH (s:Student)-[r:STUDY]->(c:Course)
WHERE r.score >= 80 AND r.score <= 90
RETURN s.name, c.name, r.score

// 3. 模糊查询:课程名包含「数据库」的课程
MATCH (c:Course)
WHERE c.name CONTAINS "数据库" // 还可用 STARTS WITH(以...开头)/ ENDS WITH(以...结尾)
RETURN c.name, c.type;

4.聚合查询:COUNT/SUM/AVG/MIN/MAX(统计分析用)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 1. 统计学生总数、课程总数
MATCH (s:Student) RETURN COUNT(s) AS student_count;
MATCH (c:Course) RETURN COUNT(c) AS course_count;

// 2. 计算Python基础的平均成绩、最高/最低成绩
MATCH (s)-[r:STUDY]->(c:Course {name: "Python基础"})
RETURN
AVG(r.score) AS avg_score,
MAX(r.score) AS max_score,
MIN(r.score) AS min_score,
COUNT(s) AS study_count; // 选课人数

// 3. 统计每个学生的选课门数和总成绩,按选课门数降序
MATCH (s:Student)-[r:STUDY]->(c:Course)
WITH s, COUNT(c) AS course_num, SUM(r.score) AS total_score // WITH 临时传递结果
RETURN s.name, course_num, total_score
ORDER BY course_num DESC;

5.多跳关系查询:路径查询(查间接关联,如「学生→课程→老师」)

1
2
3
4
5
6
7
8
9
10
11
12
// 1. 查询张三的所有授课老师(学生→课程→老师,2跳关系)
MATCH (s:Student {name: "张三"})-[r1:STUDY]->(c:Course)<-[r2:TEACH]-(t:Teacher)
RETURN s.name, c.name, t.name;

// 2. 通用路径查询:匹配张三和所有老师的最短路径(*表示任意跳数,1..3表示1-3跳)
MATCH p=shortestPath((s:Student {name: "张三"})-[*]-(t:Teacher))
RETURN p;

// 3. 查询教过选修课程的老师,且老师年龄<40
MATCH (t:Teacher)-[r:TEACH]->(c:Course {type: "选修"})
WHERE t.age < 40
RETURN DISTINCT t.name; // DISTINCT 去重,避免老师教多门选修课重复显示

四、修改操作:SET (修改节点 / 关系的属性,新增 / 更新)

SET新增属性(节点 / 关系无该属性时)或更新属性(已有该属性时),搭配MATCH定位要修改的对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 1. 修改节点属性:张三年龄加1,新增「专业」属性
MATCH (s:Student {name: "张三"})
SET s.age = s.age + 1, s.major = "计算机科学与技术"
RETURN s;

// 2. 修改关系属性:张三的Python基础成绩改为95
MATCH (s:Student {name: "张三"})-[r:STUDY]->(c:Course {name: "Python基础"})
SET r.score = 95
RETURN s.name, c.name, r.score;

// 3. 批量修改:所有必修课程学分加1
MATCH (c:Course {type: "必修"})
SET c.credit = c.credit + 1
RETURN c.name, c.credit;

五、删除操作:DELETE / REMOVE (别搞混!)

关键区别:

  • DELETE:删除节点关系(删除节点前必须先删除其所有关系,否则报错)
  • REMOVE:删除节点 / 关系的属性(不是删除对象本身)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ******************** REMOVE:删除属性 ********************
// 删除张三的「专业」属性
MATCH (s:Student {name: "张三"})
REMOVE s.major
RETURN s;

// ******************** DELETE:删除关系 ********************
// 删除王五选Python基础的关系
MATCH (s:Student {name: "王五"})-[r:STUDY]->(c:Course {name: "Python基础"})
DELETE r
RETURN s, c;

// ******************** DELETE:删除节点(先删关系再删节点) ********************
// 删除课程C003(Java开发):先删其所有关系,再删节点
MATCH (c:Course {id: "C003"})-[r]-() // [r]-() 匹配该课程的所有入/出关系
DELETE r, c // 先删关系r,再删节点c
RETURN "删除成功";

// ******************** 清空所有数据(谨慎!生产环境禁用) ********************
MATCH (n) DETACH DELETE n; // DETACH DELETE 自动删除节点的所有关系,再删除节点

六、索引与约束(优化查询,保证数据唯一性)

当数据量变大时,索引能大幅提升查询速度;约束能保证节点属性的唯一性(如学号、课程号不能重复),新手提前了解,后续实战必用。

1. 创建索引(针对常用查询的属性,如学生 id、课程名)

1
2
3
4
5
// 为Student的id属性创建索引
CREATE INDEX idx_student_id FOR (s:Student) ON (s.id);

// 为Course的name属性创建索引
CREATE INDEX idx_course_name FOR (c:Course) ON (c.name);

2.创建唯一约束(保证属性值唯一,比索引更严格,重复创建会报错)

1
2
3
4
5
// 保证学生学号唯一(核心,避免重复创建同学号学生)
CREATE CONSTRAINT constraint_student_id IF NOT EXISTS FOR (s:Student) REQUIRE s.id IS UNIQUE;

// 保证课程号唯一
CREATE CONSTRAINT constraint_course_id IF NOT EXISTS FOR (c:Course) REQUIRE c.id IS UNIQUE;

3. 查看 / 删除索引 / 约束

1
2
3
4
5
6
7
8
// 查看所有索引和约束
SHOW INDEXES;

// 删除索引(根据索引名,从SHOW INDEXES结果中查)
DROP INDEX idx_course_name;

// 删除约束(根据约束名)
DROP CONSTRAINT constraint_student_id;

neo4j入门
http://hanqichuan.com/2026/02/03/其他工具/neo4j入门/
作者
韩启川
发布于
2026年2月3日
许可协议