如何扩展 Cypher

本指南介绍了如何创建、使用和部署用户自定义过程(Procedures)和函数(Functions),这是 Neo4j 查询语言 Cypher® 的扩展机制。

扩展 Cypher

Cypher 是一种功能强大且富有表现力的语言,具有一流的图模式和集合支持。但有时您需要实现超出其当前功能的操作,例如附加的图算法、并行化或自定义转换。

Cypher 可以通过用户自定义过程和函数进行扩展,具体描述请参阅 Java 参考手册 → 用户自定义过程Java 参考手册 → 用户自定义函数

Neo4j 本身也提供并使用自定义过程。Neo4j Browser 暴露的许多监控、内省和安全功能都是通过过程实现的。

procedures functions bolt

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

可用过程的集合取决于您的安装类型和配置设置。结果可能如下所示

package count names

["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 手册 → 用户自定义函数

您可以获取任何过程库并将其部署到您的自托管服务器,以启用额外的过程和函数。

部署过程和函数

如果您构建自己的过程或从社区项目下载它们,它们会被打包在 JAR 文件中。您可以将该文件复制到 Neo4j 服务器的 $NEO4J_HOME/plugins 目录中并重启服务。

由于过程和函数使用底层 Java API,它们可以访问所有 Neo4j 内部结构以及文件系统和机器。这就是为什么您应该了解所部署的过程及其用途。仅从受信任的来源安装过程。如果是开源的,请检查其源代码,最好自己构建。

请参阅 操作手册 → 确保扩展安全,了解如何确保这些添加组件的安全性的最佳实践。

某些过程和函数可用于自托管的 Neo4j 企业版和社区版。
本节描述的自定义代码不兼容 AuraDB
在 Neo4j AuraDB 中,可用过程和函数的集合仅限于内置过程和 APOC Core 库的子集。

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
time date unixtime millis

"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 8 Stream

  • 这些字段名称会转换为可供 YIELD 使用的结果列

以下内容对两者均适用

  • 接收 @Name 注解的参数(带有可选的默认值)

  • 可以使用注入的 @Context public GraphDatabaseService

  • 在 Cypher 语句的事务中运行

  • 支持的参数和结果类型为: Long, Double, Boolean, String, Node, Relationship, Path, Object