如何扩展 Cypher
本指南解释了如何创建、使用和部署用户定义的存储过程和函数,这是 Neo4j 查询语言 Cypher® 的扩展机制。
扩展 Cypher
Cypher 是一种强大且富有表现力的语言,具有一流的图模式和集合支持。但有时您需要执行其当前功能之外的操作,例如附加图算法、并行化或自定义转换。
Cypher 可以通过用户定义的存储过程和函数进行扩展,如Java 参考 → 用户定义的存储过程和Java 参考 → 用户定义的函数中所述。
Neo4j 本身提供并利用了自定义存储过程。Neo4j Browser 暴露的许多监控、自检和安全功能都是使用存储过程实现的。

Neo4j 中的存储过程和函数
-
函数是简单的计算/转换,并返回单个值。
-
函数可以在任何表达式或谓词中使用。
-
存储过程是更复杂的操作,并生成结果流。
-
存储过程可以生成、获取或计算数据,使其可用于 Cypher 查询中的后续处理步骤。
-
要调用部署在数据库中的存储过程,请使用
CALL
子句(更多详细信息,请参阅Cypher 手册 → CALL 过程)。
列出和使用 Neo4j 中的函数和存储过程
Neo4j 附带了许多内置存储过程。要了解更多信息,请参阅操作手册 → 存储过程。
要列出 DBMS 中所有可用的函数和存储过程,请使用以下 Cypher 命令
-
SHOW FUNCTIONS
-
SHOW PROCEDURES
您可以参考 Cypher 速查表,快速了解如何使用这些命令。
每个存储过程返回一列或多列数据。通过 YIELD
子句,这些列可以被选择并可以设置别名,然后可在您的 Cypher 查询中使用。
与其他 Cypher 管理命令一样,SHOW PROCEDURES
可以与部分 Cypher 子句一起使用,如下所示,我们按“db.”前缀过滤并按名称返回结果。
SHOW PROCEDURES
YIELD name, signature, description as text
WHERE name STARTS WITH 'db.'
RETURN * ORDER BY name ASC
下面您可以找到另一个示例,说明如何按所选类别(例如按包)对可用存储过程进行分组。
SHOW PROCEDURES
YIELD name, signature, description
RETURN split(name,".")[0..-1] AS package, count(*) AS count,
collect(split(name,".")[-1]) AS names
ORDER BY count DESC
可用存储过程的集合取决于您的安装类型和配置设置。结果可以是以下内容:
包 | 计数 | 名称 |
---|---|---|
["dbms"] |
20 |
["checkConfigValue", "components", "info",…] |
["db"] |
16 |
["awaitIndex", "awaitIndexes", "checkpoint",…] |
["db","stats"] |
6 |
["clear", "collect", "retrieve",…] |
["dbms", "cluster"] |
6 |
["checkConnectivity", "cordonServer", "protocols",…] |
["db", "index", "fulltext"] |
4 |
["awaitEventuallyConsistentIndexRefresh", "listAvailableAnalyzers",…] |
用户定义的函数是用 Java 编写的,部署到数据库中,并以与任何其他 Cypher 函数相同的方式调用。可以开发和使用的函数主要有两种类型:
-
用户定义的标量函数,
-
用户定义的聚合函数。
更多详细信息,请参阅Cypher 手册 → 用户定义的函数。
您可以获取任何存储过程库并将其部署到您的自管理服务器,以提供额外的存储过程和函数。
另请参阅 Neo4j Java 参考中的存储过程部分。
部署存储过程和函数
如果您构建自己的存储过程或从社区项目下载它们,它们将打包在一个 JAR 文件中。您可以将该文件复制到 Neo4j 服务器的 $NEO4J_HOME/plugins
目录并重新启动。
由于存储过程和函数使用低级 Java API,它们可以访问所有 Neo4j 内部结构以及文件系统和机器。这就是为什么您应该了解您部署哪些存储过程以及为什么部署。只安装来自可信来源的存储过程。如果它们是开源的,请检查其源代码,最好自行构建。 有关如何确保这些扩展安全性的最佳实践,请参阅操作手册 → 保护扩展。 |
某些存储过程和函数适用于自管理的 Neo4j 企业版和社区版。 |
存储过程和函数库
APOC Core 库为您提供了一组关于 Cypher 的有用存储过程,以增加数据集成、图算法和数据转换领域的功能。
例如,用于格式化和解析不同分辨率时间戳的函数:
RETURN apoc.date.format(timestamp()) as time,
apoc.date.format(timestamp(),'ms','yyyy-MM-dd') as date,
apoc.date.parse('13.01.1975','s','dd.MM.yyyy') as unixtime,
apoc.date.parse('2017-01-05 13:03:07') as millis
时间 | 日期 | Unix 时间 | 毫秒 |
---|---|---|---|
"2017-01-05 13:06:39" |
"2017-01-05" |
158803200 |
1483621387000 |
在我们的 Neo4j Labs 项目中,您可以找到由我们的社区和员工构建的一组库。查看一下,看看有哪些可用的。您的许多需求将已经通过这些库得到满足,例如:
-
索引操作
-
数据库/API 集成
-
图重构
-
导入和导出
-
空间索引查找
-
RDF 导入和导出
-
等等
社区和 Neo4j Labs 项目没有官方支持,我们不提供任何 SLA 或关于向后兼容性和弃用的保证。 |
开发您自己的存储过程和函数
您可以在 Neo4j Java 参考中找到有关编写和测试存储过程的详细信息。
示例 GitHub 存储库包含详细的文档和注释,您可以直接克隆并用作起点。
这里只是一些初始提示。
用户定义的函数更简单,我们先从它们开始:
-
@UserFunction
是类中带注解的公共 Java 方法 -
它们的默认名称是 package-name.method-name
-
它们返回单个值
-
它们是只读的
用户定义的存储过程类似:
-
@Procedure
注解的 Java 方法 -
带有一个额外的
mode
属性(READ, WRITE, DBMS
) -
返回一个带有
public
字段的简单对象的 Java 8Stream
-
这些字段名称将转换为可用于
YIELD
的结果列
这些适用于两者:
-
接受
@Name
注解的参数(带有可选的默认值) -
可以使用注入的
@Context public GraphDatabaseService
-
在 Cypher 语句的事务中运行
-
参数和结果支持的类型有:
Long, Double, Boolean, String, Node, Relationship, Path, Object