自定义、基于 Cypher 的过程与函数
默认情况下,自定义 Cypher 语句是启用的。我们可以通过在 apoc.conf 中设置以下属性来禁用它:
apoc.custom.procedures.enabled=false
|
所有这些过程(列出和显示过程除外)都旨在系统数据库中执行,因此必须通过开启系统数据库会话来执行。有几种实现方式:- 使用 cypher-shell 或 Neo4j Browser 时,可以在 Cypher 查询前加上 此外,它们接受数据库名称作为第一个参数,指定要在其中安装/更新/移除自动 UUID 的目标数据库。通过此实现,我们可以利用集群路由机制在集群环境中使用这些过程。 |
|
安装、更新或移除自定义 Cypher 语句是一个最终一致性操作。因此,它们不会立即被添加/更新/移除,而是由 Apoc 配置 在集群环境中, |
| 限定名称 | 类型 | 版本 |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
概述
我一直希望能够将 Cypher 语句注册为标准的过程和函数,以便它们可以以独立的方式被调用。
你可以通过调用 apoc.custom.installProcedure 和 apoc.custom.installFunction 过程来实现这一点。它们会注册给定的 Cypher 语句,前缀为 custom.* 命名空间,并覆盖可能存在的同名定义,因此你可以根据需要重新定义它们。
apoc.custom.installProcedure 和 apoc.custom.installFunction 过程的第一个参数是你想要创建的过程/函数的签名。
这看起来与 SHOW PROCEDURES YIELD signature、SHOW 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。
如果你想创建一个带有默认 String 参数的过程/函数,且该参数包含空格、引号(例如:"my text ' with ' quote")或 "null"(作为字符串),则必须引用该结果,例如 CALL apoc.custom.declareProcedure("procWithNullString(param='null'::STRING)::(output::STRING)", 'return $param as output') |
签名参数中的 typeParam 和 typeResult 可以是以下值之一
-
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-vs-map-result])
-
LIST TYPE, LIST OF TYPE(其中
TYPE可以是上述值之一) -
ANY
在 Neo4j 5.13 中,NUMBER 类型被 INTEGER | FLOAT 取代,但为了向后兼容,我们仍然可以使用它。 |
如果你覆盖了过程或函数,可能需要调用 call db.clearQueryCaches(),因为对内部 ID 的查找会保存在编译后的查询计划中。 |
|
从 5.11 版本开始,如果你执行 因此,我们必须开启一个新的事务来执行所声明的自定义过程/函数。 |
以下示例假设我们处于 neo4j 数据库中,并且希望在该数据库中创建自定义过程/函数。
使用 apoc.custom.installProcedure 的自定义过程
| 过程、输入和输出名称必须至少包含 2 个字符。 |
这是一个简单的示例
CALL apoc.custom.installProcedure('answerInteger() :: (answer::INT)', 'RETURN 42 as answer')
这会在 由配置 apoc.custom.procedures.refresh 定义的时间后 注册一个过程 custom.answer,然后你就可以调用它了。
CALL custom.answerInteger
| answer |
|---|
42 |
或者你也可以这样写
CALL apoc.custom.installProcedure('answer() :: (row::MAP)', 'RETURN 42 as answer')
在这种情况下,结果被包装在名为 row 的映射流中。因此,你可以执行
CALL custom.answer()
YIELD row
RETURN row.answer
| 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);
| answer |
|---|
1.0 |
4.0 |
16.0 |
64.0 |
此外,通过第 3 个参数,我们可以在 neo4j 之外的数据库中创建自定义过程。例如,以下语句在 foo 数据库中创建了一个自定义过程
CALL apoc.custom.installProcedure('foodb() :: (row::INT)', 'RETURN 42 as row', 'foo')
此外,我们可以将字符串作为第 4 个参数传递以指定过程模式(默认 "WRITE")。它可以是:- "READ" - 如果过程仅对图执行读取操作 - "WRITE" - 如果它可能对图执行读取和写入操作 - "SCHEMA" - 如果它将对模式执行操作 - "DBMS" - 如果它将执行系统操作 - 即不针对图执行
同样,我们可以将 description 作为第 5 个参数传递,该参数将由 call apoc.custom.list 和 SHOW PROCEDURES 返回。
使用 apoc.custom.installFunction 的自定义函数
| 函数、输入和输出名称必须至少包含 2 个字符。 |
这是一个简单的示例
CALL apoc.custom.installFunction('answerFun() :: INT', 'RETURN 42 as answer')
这会在 由配置 apoc.custom.procedures.refresh 定义的时间后 将该语句注册为过程 custom.answer,然后你就可以调用它了。
RETURN custom.answerFun()
| answer |
|---|
42 |
或者你也可以这样写
CALL apoc.custom.installFunction('answerFunMap() :: MAP', 'RETURN 42 as answer')
在这种情况下,结果被包装在名为 row 的映射流中。因此,你可以执行
WITH custom.answerFunMap() YIELD row
RETURN row.answer
| answer |
|---|
42 |
我们可以运行以下函数来创建 custom.double 函数,它将提供的值翻倍
CALL apoc.custom.installFunction(
'double(input::INT) :: INT',
'RETURN $input*2 as answer'
);
我们可以使用此函数,如下面的查询所示
RETURN custom.double(83) AS value;
| 值 |
|---|
166 |
此外,通过第 3 个参数,我们可以在 neo4j 之外的数据库中创建自定义过程。例如,以下语句在 foo 数据库中创建了一个自定义过程
CALL apoc.custom.installFunction('foodb() :: INT', 'RETURN 42', 'foo')
此外,我们可以传递一个布尔值(默认为 false)作为第 4 个参数,如果为 true,且函数返回单个元素的列表,它将只返回该元素本身,而不是列表。
例如:
CALL apoc.custom.installFunction('forceSingleTrue(input::ANY) :: LIST OF INT',
'RETURN 1',
true
);
| 值 |
|---|
1 |
否则,如果为 false,结果将是一个单元素列表
CALL apoc.custom.installFunction('forceSingleFalse(input::ANY) :: LIST OF INT',
'RETURN 1',
false
);
| 值 |
|---|
[1] |
同样,我们可以将 description 作为第 5 个参数传递,该参数将由 call apoc.custom.list 和 SHOW FUNCTIONS 返回。
使用 apoc.custom.list 列出已注册的过程/函数
过程 apoc.custom.list 提供通过 apoc.custom.installProcedure 和 apoc.custom.installFunction 注册的所有过程/函数的列表
给定此调用
CALL apoc.custom.list
输出将如下表所示
| type | 名称 (name) | description(描述) | mode | statement | inputs(输入) | outputs(输出) | forceSingle(强制单个返回) |
|---|---|---|---|---|---|---|---|
"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>)
字段
| 参数 | description(描述) |
|---|---|
名称 (name) |
过程名称 |
数据库名称 (databaseName) |
数据库名称(默认: |
移除过程 apoc.custom.dropFunction
过程 apoc.custom.dropFunction 允许从特定数据库(默认为 neo4j)中删除指定的自定义函数,时间由配置 apoc.custom.procedures.refresh 定义。
给定此调用
CALL apoc.custom.dropFunction(<name>)
字段
| 参数 | description(描述) |
|---|---|
名称 (name) |
函数名称 |
数据库名称 (databaseName) |
数据库名称(默认: |
导出元数据
|
要将自定义过程导入另一个数据库(例如在 |