如何扩展 Cypher

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

扩展 Cypher

Cypher 是一种功能强大且表达力强的语言,具有一流的图模式和集合支持。但有时您需要做的事情超出了它目前提供的功能,例如额外的图算法、并行化或自定义转换。

Cypher 可以通过用户定义的过程和函数进行扩展,如Java 参考 → 用户定义的过程Java 参考 → 用户定义的函数中所述。

Neo4j 本身提供并使用自定义过程。**Neo4j 浏览器**公开的许多监控、内省和安全功能都是使用过程实现的。

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

可用过程的集合取决于您拥有的安装类型和配置设置。结果可能是以下内容

计数 名称

["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 Enterprise Edition 和 Community Edition。
本节中描述的自定义代码与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
时间 日期 unix时间 毫秒

"2017-01-05 13:06:39"

"2017-01-05"

158803200

1483621387000

在我们的Neo4j Labs 项目中,您可以找到由我们的社区和员工构建的一组库。查看它以了解已经存在的内容。您的许多需求可能已经被这些内容所涵盖,例如

  • 索引操作

  • 数据库/API 集成

  • 图重构

  • 导入和导出

  • 空间索引查找

  • rdf 导入和导出

  • 等等

社区和 Neo4j Labs 项目不提供官方支持,我们不提供任何有关向后兼容性和弃用的 SLA 或保证。

开发您自己的过程和函数

您可以在Neo4j Java 参考中找到有关编写和测试过程的详细信息。

示例 GitHub 存储库包含详细的文档和注释,您可以直接克隆并用作起点。

以下是一些初步提示。

用户定义函数更简单,所以让我们从它们开始

  • @UserFunction是类中带注释的公共 Java 方法

  • 它们的默认名称是包名称.方法名称

  • 它们返回单个值

  • 是只读的

用户定义的过程与此类似

  • 使用@Procedure注解的Java方法

  • 带有额外的mode属性(READ, WRITE, DBMS

  • 返回一个包含简单对象的Java 8 Stream,这些对象具有public字段

  • 这些字段名称将转换为可用于YIELD的结果列

以下内容对两者均有效:

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

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

  • 在Cypher语句的事务中运行

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