ChatGPT实现
ChatGPT实现包括数据预处理、
以学生选课场景为例来进行对比
背景说明
假设我们有一个高校教务系统,包含以下实体:
- 学生(Student):有学号、姓名
- 课程(Course):有课程编号、课程名、学分
- 选课关系(Enroll):学生选了某门课,可能包含成绩(grade)
在关系型数据库中,这通常用三张表实现;在 Neo4j 中,则用节点和关系直接建模。
索引用于加速查找起点(如按学号找学生、按课程名找课)。
| SQL | Cypher |
|---|---|
| CREATE INDEX idx_student_id ON students (student_id); CREATE INDEX idx_course_name ON courses (course_name); |
CREATE INDEX Student_studentId IF NOT EXISTS FOR (s:Student) ON s.studentId; CREATE INDEX Course_courseName IF NOT EXISTS FOR (c:Course) ON c.courseName; |
💡 注意:Neo4j 的索引只用于
MATCH的起点(如(s:Student {studentId: '2023001'})),后续遍历靠图结构,无需 JOIN。
| SQL | Cypher |
|---|---|
| SELECT * FROM students; | MATCH (s:Student) RETURN s; |
需求:列出学分最高的前 5 门课程。
| SQL | Cypher |
|---|---|
| SELECT course_name, credits FROM courses ORDER BY credits DESC LIMIT 5; | MATCH (c:Course) RETURN c.courseName, c.credits ORDER BY c.credits DESC LIMIT 5; |
需求:查找课程名为 “数据库原理” 的课程信息。
| SQL | Cypher |
|---|---|
| SELECT course_name, credits FROM courses WHERE course_name = ‘数据库原理’; | MATCH (c:Course {courseName: ‘数据库原理’}) RETURN c.courseName, c.credits; |
更简洁:属性直接写在
{}中,无需WHERE。
需求:查找 “高等数学” 和 “线性代数” 两门课的信息。
| SQL | Cypher |
|---|---|
| SELECT course_name, credits FROM courses WHERE course_name IN (‘高等数学’, ‘线性代数’); | MATCH (c:Course) WHERE c.courseName IN [‘高等数学’, ‘线性代数’] RETURN c.courseName, c.credits; |
需求:查找课程名以 “数据” 开头 且 学分 ≥ 3 的课程。
| SQL | Cypher |
|---|---|
| SELECT course_name, credits FROM courses WHERE course_name LIKE ‘数据%’ AND credits >= 3; | MATCH (c:Course) WHERE c.courseName STARTS WITH ‘数据’ AND c.credits >= 3 RETURN c.courseName, c.credits; |
💡 Neo4j 用
STARTS WITH/CONTAINS/ENDS WITH替代LIKE,更直观。
需求:找出选了 “数据库原理” 的所有学生姓名。
1 | SELECT DISTINCT s.name |
1 | MATCH (c:Course {courseName: '数据库原理'}) <-[:ENROLL]- (s:Student) |
无需 JOIN!关系本身就是路径。
关系类型:ENROLL直接表达了“学生选课”的语义。
需求:统计每门课程有多少人选,按人数降序,取前 3。
| SQL | Cypher |
|---|---|
| SELECT c.course_name, COUNT(e.student_id) AS studentCount FROM courses c LEFT JOIN enrollments e ON c.course_id = e.course_id GROUP BY c.course_id, c.course_name ORDER BY studentCount DESC LIMIT 3; | MATCH (c:Course) OPTIONAL MATCH (c) <-[:ENROLL]- (s:Student) RETURN c.courseName, COUNT(s) AS studentCount ORDER BY studentCount DESC LIMIT 3; |
💡
OPTIONAL MATCH相当于LEFT JOIN,确保没被选的课也显示(人数为 0)。
需求:计算学生 “张三” 已修课程的总学分。
| SQL | Cypher |
|---|---|
| SELECT SUM(c.credits) AS totalCredits FROM students s JOIN enrollments e ON s.student_id = e.student_id JOIN courses c ON e.course_id = c.course_id WHERE s.name = ‘张三’; | MATCH (s:Student {name: ‘张三’}) -[:ENROLL]-> (c:Course) RETURN sum(c.credits) AS totalCredits; |
图遍历天然支持“从学生出发,走到课程,累加学分”。
需求:列出每位学生及其所选课程名(逗号分隔或列表形式)。
| SQL | Cypher |
|---|---|
| SELECT s.name, STRING_AGG(c.course_name, ‘, ‘ ORDER BY c.course_name) AS courses FROM students s JOIN enrollments e ON s.student_id = e.student_id JOIN courses c ON e.course_id = c.course_id GROUP BY s.student_id, s.name ORDER BY s.name; | MATCH (s:Student) -[:ENROLL]-> (c:Course) RETURN s.name, COLLECT(c.courseName) AS courses ORDER BY s.name; |
COLLECT()自动将多行合并为列表,结果更结构化(适合 JSON 输出)。
| 场景 | SQL 特点 | Cypher 优势 |
|---|---|---|
| 多表连接 | 需显式 JOIN,易错、性能差(尤其深度关联) |
关系即路径,直接 MATCH (A)-[R]->(B) |
| 聚合分组 | 必须写 GROUP BY 所有非聚合字段 |
隐式分组,简洁 |
| 返回嵌套结构 | 需用 STRING_AGG 或应用层处理 |
内置 COLLECT(),天然支持嵌套 |
| 查询可读性 | 逻辑隐藏在 JOIN 条件中 | 像画图一样写查询,语义清晰 |
Neo4j 图数据库将数据存储为节点、关系和属性,而不是以表格或文档形式。
节点 表示图数据模型中的实体或离散对象。节点可以通过关系连接,在属性中存储数据,并按标签分类
一个节点可以有多个标签 (:User:Customer)
如:
1 | (:Person {name: "张三", age: 30}) |
关系 表示图数据模型中节点之间的连接。关系将源节点连接到目标节点,在属性中存储数据,并按类型分类
KNOWS, BOUGHT)1 | (:Person {name: "张三"})-[:FRIEND]->(:Person {name: "李四"}) |
属性 用于在节点和关系上存储数据的键值对
| 概念 | MySQL(关系型) | Neo4j(图数据库) |
|---|---|---|
| 基本单元 | 表(Table)、行(Row) | 节点(Node)、关系(Relationship) |
| 连接方式 | 外键(JOIN) | 直接存储关系(关系是一等公民) |
| 查询语言 | SQL | Cypher(声明式、直观) |
| 性能特点 | JOIN 越多越慢 | 深度关联查询极快(O(1) 跳转) |
| 数据模型 | 表格(二维) | 图(网络结构) |
本文档适用于在 CentOS 7 环境下使用源代码部署 Dify 应用,对应版本
1.9.2。由于系统较旧,部分依赖需手动升级或通过容器化方式解决兼容性问题。
1 | sudo yum remove docker \ |
1 | sudo yum install -y yum-utils device-mapper-persistent-data lvm2 |
1 | sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo |
1 | sudo yum install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
1 | sudo systemctl start docker |