存储过程 #
一、存储过程概述 #
1.1 什么是存储过程 #
存储过程是预编译的可重用代码块,可以执行复杂操作。
text
存储过程特点:
├── 封装复杂逻辑
├── 提高代码复用
├── 支持参数传递
├── 可返回多个结果
└── 可用Java编写
1.2 内置存储过程 #
Neo4j提供多种内置存储过程:
| 类别 | 示例 |
|---|---|
| 数据库管理 | db.labels, db.relationshipTypes |
| 索引管理 | db.indexes, db.awaitIndex |
| 事务管理 | dbms.listTransactions |
| 用户管理 | dbms.security.listUsers |
二、CALL语句 #
2.1 基本语法 #
cypher
CALL procedure.name()
2.2 带参数调用 #
cypher
CALL procedure.name(param1, param2)
2.3 使用YIELD返回结果 #
cypher
CALL db.labels() YIELD label
RETURN label
2.4 过滤结果 #
cypher
CALL db.indexes() YIELD name, state
WHERE state = 'ONLINE'
RETURN name
2.5 与其他子句组合 #
cypher
CALL db.labels() YIELD label
MATCH (n)
WHERE label IN labels(n)
RETURN label, count(n) AS count
ORDER BY count DESC
三、内置存储过程 #
3.1 数据库信息 #
cypher
CALL db.info()
3.2 标签列表 #
cypher
CALL db.labels()
3.3 关系类型列表 #
cypher
CALL db.relationshipTypes()
3.4 属性键列表 #
cypher
CALL db.propertyKeys()
3.5 索引列表 #
cypher
CALL db.indexes()
3.6 约束列表 #
cypher
CALL db.constraints()
3.7 统计信息 #
cypher
CALL db.stats.retrieve('GRAPH COUNTS')
四、APOC库 #
4.1 APOC概述 #
APOC (Awesome Procedures on Cypher) 是Neo4j最流行的扩展库。
text
APOC功能:
├── 数据转换
├── 图算法
├── 文本处理
├── 日期时间
├── 数学运算
├── 集合操作
├── 虚拟关系
└── 批处理
4.2 安装APOC #
- 下载APOC jar文件
- 放入plugins目录
- 重启Neo4j
或在neo4j.conf中配置:
properties
dbms.security.procedures.unrestricted=apoc.*
dbms.security.procedures.allowlist=apoc.*
4.3 查看APOC过程 #
cypher
CALL apoc.help('all')
4.4 常用APOC函数 #
文本处理 #
cypher
RETURN apoc.text.replace('Hello World', 'World', 'Neo4j')
RETURN apoc.text.capitalize('hello')
RETURN apoc.text.capitalizeAll('hello world')
集合操作 #
cypher
RETURN apoc.coll.union([1, 2], [2, 3])
RETURN apoc.coll.intersection([1, 2, 3], [2, 3, 4])
RETURN apoc.coll.difference([1, 2, 3], [2, 3, 4])
日期时间 #
cypher
RETURN apoc.date.currentTimestamp()
RETURN apoc.temporal.format(date(), 'yyyy-MM-dd')
JSON处理 #
cypher
RETURN apoc.convert.toJson({name: 'Tom', age: 30})
RETURN apoc.convert.fromJsonMap('{"name":"Tom","age":30}')
4.5 APOC图操作 #
批量创建 #
cypher
CALL apoc.create.nodes(['Person'], [
{name: 'Tom'},
{name: 'Jerry'}
])
批量处理 #
cypher
CALL apoc.periodic.iterate(
'MATCH (p:Person) RETURN p',
'SET p.processed = true',
{batchSize: 1000}
)
路径展开 #
cypher
MATCH (start:Person {name: 'Tom'})
CALL apoc.path.expand(start, 'KNOWS>', null, 1, 3) YIELD path
RETURN path
4.6 APOC虚拟关系 #
cypher
MATCH (a:Person)-[:KNOWS]->(b:Person)
WITH a, count(b) AS friendCount
CALL apoc.create.vRelationship(a, 'FRIEND_COUNT', {count: friendCount}, null) YIELD rel
RETURN a, rel
五、自定义存储过程 #
5.1 创建Java存储过程 #
java
package com.example;
import org.neo4j.procedure.*;
import org.neo4j.graphdb.*;
public class CustomProcedures {
@Context
public GraphDatabaseService db;
@Procedure(name = "com.example.hello", mode = Mode.READ)
@Description("Returns a hello message")
public Stream<HelloResult> hello(@Name("name") String name) {
return Stream.of(new HelloResult("Hello, " + name + "!"));
}
public static class HelloResult {
public String message;
public HelloResult(String message) {
this.message = message;
}
}
}
5.2 注册存储过程 #
- 编译Java代码为JAR文件
- 放入plugins目录
- 重启Neo4j
5.3 调用自定义过程 #
cypher
CALL com.example.hello('Tom') YIELD message
RETURN message
六、存储过程最佳实践 #
6.1 性能优化 #
text
建议:
├── 使用索引加速查询
├── 限制返回结果数量
├── 使用分批处理大数据量
├── 避免复杂计算
└── 合理使用缓存
6.2 安全考虑 #
text
安全建议:
├── 限制存储过程权限
├── 验证输入参数
├── 避免SQL注入
├── 使用参数化查询
└── 记录操作日志
6.3 错误处理 #
cypher
CALL apoc.do.when(
EXISTS((:Person {name: 'Tom'})),
'RETURN "Person exists" AS result',
'CREATE (p:Person {name: "Tom"}) RETURN "Person created" AS result',
{}
) YIELD value
RETURN value.result
七、实际应用示例 #
7.1 批量数据导入 #
cypher
CALL apoc.periodic.iterate(
'LOAD CSV WITH HEADERS FROM "file:///data.csv" AS row RETURN row',
'CREATE (p:Person {id: row.id, name: row.name})',
{batchSize: 1000, parallel: true}
)
7.2 数据清理 #
cypher
CALL apoc.periodic.iterate(
'MATCH (p:Person) WHERE p.status = "deleted" RETURN p',
'DETACH DELETE p',
{batchSize: 1000}
)
7.3 图遍历 #
cypher
MATCH (start:Person {name: 'Tom'})
CALL apoc.path.expandConfig(start, {
relationshipFilter: 'KNOWS>',
minLevel: 1,
maxLevel: 3,
uniqueness: 'NODE_GLOBAL'
}) YIELD path
RETURN path
7.4 数据转换 #
cypher
MATCH (p:Person)
WITH p, apoc.text.capitalize(p.name) AS capitalizedName
SET p.capitalizedName = capitalizedName
八、总结 #
存储过程要点:
| 操作 | 语法 | 说明 |
|---|---|---|
| 调用过程 | CALL procedure() | 调用存储过程 |
| 返回结果 | YIELD column | 获取返回列 |
| APOC函数 | apoc.function() | APOC库函数 |
| 批量处理 | apoc.periodic.iterate() | 批量迭代处理 |
最佳实践:
- 合理使用内置过程
- 安装APOC扩展功能
- 使用批量处理提高性能
- 注意安全权限控制
- 正确处理错误
下一步,让我们学习用户权限管理!
最后更新:2026-03-27