自定义、基于 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。

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

签名参数中的 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-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')

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

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

此外,通过第 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.listSHOW PROCEDURES 返回。

使用 apoc.custom.installFunction 的自定义函数

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

这是一个简单的示例

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

这会在 由配置 apoc.custom.procedures.refresh 定义的时间后 将该语句注册为过程 custom.answer,然后你就可以调用它了。

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. 结果

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
);
表 8. 结果

1

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

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

[1]

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

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

过程 apoc.custom.list 提供通过 apoc.custom.installProcedureapoc.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)

数据库名称(默认:neo4j

移除过程 apoc.custom.dropFunction

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

给定此调用

CALL apoc.custom.dropFunction(<name>)

字段

参数 description(描述)

名称 (name)

函数名称

数据库名称 (databaseName)

数据库名称(默认:neo4j

导出元数据

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

© . This site is unofficial and not affiliated with Neo4j, Inc.