基于 Cypher 的自定义过程和函数

默认情况下,基于 Cypher 的自定义语句是启用的。我们可以通过在 apoc.conf 中设置以下属性来禁用它:

apoc.conf
apoc.custom.procedures.enabled=false

所有这些过程(列表和显示过程除外)都旨在系统数据库中执行,因此必须通过打开系统数据库会话来执行它们。有几种方法可以实现:- 使用 cypher-shell 或 Neo4j Browser 时,可以在 Cypher 查询前加上 :use system - 使用 fabric 时,可以在 Cypher 查询前加上 USE system - 使用驱动程序时,可以直接针对系统数据库打开会话

此外,它们将我们想要安装/更新/删除自动 UUID 的数据库名称作为第一个参数。通过这种实现,我们可以利用集群路由机制在集群环境中使用这些过程。

安装、更新或删除基于 Cypher 的自定义语句是最终一致性操作。因此,它们不会立即添加/更新/删除,而是具有由 Apoc 配置 apoc.custom.procedures.refresh=<MILLISECONDS> 控制的刷新率。

在集群环境中,apoc.custom.procedures.refresh 还会将过程/函数复制到每个集群成员。

表 1. 可用过程
合格名称 类型 发布

apoc.custom.dropAll

apoc.custom.dropAll() - 最终删除之前添加的所有自定义过程/函数并返回信息

过程

Apoc Extended

apoc.custom.dropFunction

apoc.custom.dropFunction() - 最终删除目标自定义函数

过程

Apoc Extended

apoc.custom.dropProcedure

apoc.custom.dropProcedure() - 最终删除目标自定义过程

过程

Apoc Extended

apoc.custom.installFunction

apoc.custom.installFunction() - 最终注册一个基于 Cypher 的自定义函数

过程

Apoc Extended

apoc.custom.installProcedure

apoc.custom.installProcedure() - 最终注册一个基于 Cypher 的自定义过程

过程

Apoc Extended

apoc.custom.list

apoc.custom.list() - 提供已注册的自定义过程/函数列表

过程

Apoc Extended

apoc.custom.show

apoc.custom.show() - 提供已注册的自定义过程/函数列表

过程

Apoc Extended

概述

我一直希望能够将 Cypher 语句注册为正式的过程和函数,以便它们可以独立调用。

您可以使用 apoc.custom.installProcedureapoc.custom.installFunction 过程调用来实现此目的。这些调用会注册给定的 Cypher 语句,并带有 custom.* 命名空间前缀,覆盖可能已存在的语句,因此您可以根据需要重新定义它们。

apoc.custom.installProcedureapoc.custom.installFunction 过程的第一个参数是您要创建的过程/函数的签名。

这类似于 SHOW PROCEDURES YIELD signatureSHOW FUNCTIONS YIELD signature Cypher 命令或 CALL apoc.help('<fun_or_procedure_name>') YIELD signature 过程返回的 signature 结果,只是没有 ?。也就是说:- 对于过程:nameProcedure(firstParam = defaultValue :: typeParam , secondParam = defaultValue :: typeParam, …​.) :: (firstResult :: typeResult, secondResult :: typeResult, …​ ) - 对于函数:nameFunction(firstParam = defaultValue :: typeParam , secondParam = defaultValue :: typeParam, …​.) :: typeResult

请注意,对于过程和函数,= defaultValue 是可选的。默认值被解析为 JSON。

如果您想创建带有包含空格、引号(例如:"my text ' with ' quote")或 "null"(作为字符串)的默认 String 参数的过程/函数,您必须引用结果,例如 CALL apoc.custom.declareProcedure("procWithNullString(param='null'::STRING)::(output::STRING)", 'return $param as output')
类型名称

signature 参数中的 typeParamtypeResult 可以是以下值之一

  • FLOAT, DOUBLE, INT, INTEGER, INTEGER | FLOAT, NUMBER, LONG

  • TEXT, STRING

  • BOOL, BOOLEAN

  • POINT, GEO, GEOMETRY

  • DATE, DATETIME, LOCALDATETIME, TIME, LOCALTIME, DURATION

  • NODE, REL, RELATIONSHIP, EDGE, PATH

  • MAP

  • MAPRESULT (对 declareFunction 有效,不会将结果包装在进一步的 map 中。参见:[map-vs-map-result])

  • LIST TYPE, LIST OF TYPE (其中 TYPE 可以是上述值之一)

  • ANY

在 Neo4j 5.13 中,NUMBER 类型被 INTEGER | FLOAT 取代,但为了向后兼容,我们仍然可以使用它。
如果您覆盖过程或函数,可能需要调用 call db.clearQueryCaches(),因为对内部 ID 的查找保存在编译后的查询计划中。

从 5.11 版本开始,如果我们执行 CALL apoc.custom.installFunction('nameFun(…​.)')CALL apoc.custom.installProcedure('nameProc(…​.)'),则无法在同一事务中分别执行 RETURN custom.nameFun(..)CALL custom.nameProc(),否则将抛出错误。

因此,我们必须打开一个新的事务来执行声明的自定义过程/函数。

以下示例假设我们在 neo4j 数据库上,并且希望在该数据库中创建自定义过程/函数。

使用 apoc.custom.installProcedure 创建自定义过程

过程、输入和输出名称必须至少包含 2 个字符。

这是一个简单示例

CALL apoc.custom.installProcedure('answerInteger() :: (answer::INT)', 'RETURN 42 as answer')

这会注册一个过程 custom.answer,然后您可以调用它,**注册时间由配置 apoc.custom.procedures.refresh 定义**。

CALL custom.answerInteger
表 2. 结果
answer

42

或者您也可以这样写

CALL apoc.custom.installProcedure('answer() :: (row::MAP)', 'RETURN 42 as answer')

在这种情况下,结果被包装在一个名为 row 的映射流中。因此,您可以执行

CALL custom.answer()
YIELD row
RETURN row.answer
表 3. 结果
answer

42

我们可以创建过程 custom.powers,它返回第一个参数的幂的流,直到并包括第二个参数提供的幂

CALL apoc.custom.installProcedure(
  'powers(input::INT, power::INT) :: (answer::INT)',
  'UNWIND range(0, $power) AS power
   RETURN $input ^ power AS answer'
);

我们可以使用此函数返回 4⁰、4¹、4² 和 4³,如下面的查询所示

CALL custom.powers(4,3);
表 4. 结果
answer

1.0

4.0

16.0

64.0

此外,通过第三个参数,我们可以在不同于 neo4j 的数据库中创建自定义过程。例如,以下过程在 foo 数据库中创建了一个自定义过程

CALL apoc.custom.installProcedure('foodb() :: (row::INT)', 'RETURN 42 as row', 'foo')

此外,我们可以将一个字符串作为第四个参数来指定过程模式(默认为 "WRITE")。它可以是:- "READ" - 如果过程仅对图执行读取操作 - "WRITE" - 如果过程可能对图执行读写操作 - "SCHEMA" - 如果过程将对模式执行操作 - "DBMS" - 如果过程将执行系统操作 - 即不对图执行操作

此外,我们可以将 description 参数作为第五个参数传递,该参数将由 call apoc.custom.listSHOW PROCEDURES 返回。

使用 apoc.custom.installFunction 创建自定义函数

函数、输入和输出名称必须至少包含 2 个字符。

这是一个简单示例

CALL apoc.custom.installFunction('answerFun() :: INT', 'RETURN 42 as answer')

这会注册一个过程 custom.answer,然后您可以调用它,**注册时间由配置 apoc.custom.procedures.refresh 定义**。

RETURN custom.answerFun()
表 5. 结果
answer

42

或者您也可以这样写

CALL apoc.custom.installFunction('answerFunMap() :: MAP', 'RETURN 42 as answer')

在这种情况下,结果被包装在一个名为 row 的映射流中。因此,您可以执行

WITH custom.answerFunMap() YIELD row
RETURN row.answer
表 6. 结果
answer

42

我们可以创建函数 custom.double,它将提供的值加倍,通过运行以下函数

CALL apoc.custom.installFunction(
  'double(input::INT) :: INT',
  'RETURN $input*2 as answer'
);

我们可以使用此函数,如下面的查询所示

RETURN custom.double(83) AS value;
表 7. 结果
value

166

此外,通过第三个参数,我们可以在不同于 neo4j 的数据库中创建自定义过程。例如,以下过程在 foo 数据库中创建了一个自定义过程

CALL apoc.custom.installFunction('foodb() :: INT', 'RETURN 42', 'foo')

此外,我们可以将一个布尔值(默认为 false)作为第四个参数传递,如果为 true,则在函数返回单个元素的列表时,它将仅返回单个元素本身而不是列表。

例如

CALL apoc.custom.installFunction('forceSingleTrue(input::ANY) :: LIST OF INT',
  'RETURN 1',
  true
);
表 8. 结果
value

1

否则如果为 false,结果将是包含单个元素的列表

CALL apoc.custom.installFunction('forceSingleFalse(input::ANY) :: LIST OF INT',
  'RETURN 1',
  false
);
表 9. 结果
value

[1]

此外,我们可以将 description 参数作为第五个参数传递,该参数将由 call apoc.custom.listSHOW FUNCTIONS 返回。

使用 apoc.custom.list 列出已注册的过程/函数

过程 apoc.custom.list 提供通过 apoc.custom.installProcedureapoc.custom.installFunction 注册的所有过程/函数的列表

给定此调用

CALL apoc.custom.list

输出将如下表所示

类型 名称 描述 模式 语句 输入 输出 强制单值

"function"

"answer"

<null>

<null>

"RETURN $input as answer"

[["input","integer | float"]]

"long"

false

"procedure"

"answer"

"Procedure that answer to the Ultimate Question of Life, the Universe, and Everything"

"read"

"RETURN $input as answer"

[["input","int","42"]]

[["answer","integer | float"]]

<null>

移除过程 apoc.custom.dropProcedure

过程 apoc.custom.dropProcedure 允许从特定数据库(默认为 neo4j)删除目标自定义过程,**删除时间由配置 apoc.custom.procedures.refresh 定义**。

给定此调用

CALL apoc.custom.dropProcedure(<name>, <databaseName>)

字段

参数 描述

名称

过程名称

databaseName

数据库名称(默认为 neo4j

移除函数 apoc.custom.dropFunction

过程 apoc.custom.dropFunction 允许从特定数据库(默认为 neo4j)删除目标自定义函数,**删除时间由配置 apoc.custom.procedures.refresh 定义**。

给定此调用

CALL apoc.custom.dropFunction(<name>)

字段

参数 描述

名称

函数名称

databaseName

数据库名称(默认为 neo4j

导出元数据

要在另一个数据库中导入自定义过程(例如在 ./neo4j-admin backup/neo4j-admin restore 之后),请参见 apoc.systemdb.export.metadata 过程。

© . All rights reserved.