虚拟资源

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

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

在某些情况下,我们希望使用来自外部源的附加数据来丰富/补充 Neo4j 图数据库中 Cypher 查询的结果,而这些数据我们无法(或不想)加载并持久化到图中。

以一个具有网络拓扑的 Neo4j 图为例:包含所有设备、它们之间的连接、依赖关系等。如果您想查询特定站点中的所有设备并返回过去两个小时的性能指标。这就是“时间序列数据”,您可能不想将其导入并持久化在图中。apoc.dv 为您提供了在查询时按需访问该信息,并将其与图中网络拓扑数据无缝结合的选项。

APOC 扩展库支持定义虚拟资源目录。虚拟资源是一种外部数据源,Neo4j 可以使用它按需查询和检索数据,并将其呈现为虚拟节点,从而丰富图中存储的数据。虚拟资源目录功能结合了两个 APOC 元素

  • 用于从外部源查询数据的 apoc.load.* 过程

  • 用于创建瞬态图结构的虚拟过程,这些结构可以作为查询结果返回,但永远不会在图中持久化。

从高层来看,虚拟资源目录功能将外部数据源连接的定义与实际查询分离开来。它提供了管理虚拟化资源目录(创建/删除/修改虚拟化资源)以及查询它们的过程。在当前版本中,支持关系型 (RDB) 数据源和 CSV 文件。

apoc.dv.high level

以下示例的图和 RDB

此示例使用存储在 Postgres 中的数据库。您可以使用此脚本重新创建它。它仅包含三张表

apoc.dv.rdb schema diagram

我们已经在 Neo4j 中导入了区域和部门(导入脚本作为附件提供),但没有导入城镇,我们将对其进行虚拟化,仅在需要时从 RDB 中检索。图的结构如下(片段)

apoc.dv.imported graph from RDB

通过 JDBC 管理虚拟化资源

创建虚拟化资源 (JDBC)

在查询虚拟化资源之前,我们需要先定义它。我们使用 apoc.dv.catalog.install 过程来完成此操作。该过程接受三个参数

  • 一个唯一标识虚拟化资源的名称,可用于查询该资源

  • 我们想要使用该资源的数据库名称(默认为 'neo4j'

  • 一组参数,指示资源类型 (type)、访问点 (url)、将在访问点上运行的参数化查询 (query) 以及将应用于生成的虚拟节点的标签 (labels)。

我们正在关系数据库上定义一个虚拟化资源(类型:JDBC),该资源可在本地访问(url: "jdbc:postgresql:///communes?user=jb&password=jb"),它将返回我们标记为 Town 和 PopulatedPlace 的节点——生成的节点将有两个标签(labels: ["Town","PopulatedPlace"])。我们还提供了 SQL 查询,包括它需要的参数,这些参数将在查询时传递。最后,我们可以包含一段描述性信息,帮助用户了解虚拟资源产生的内容以及如何使用它。以下是创建此类虚拟化资源的 Cypher

CALL apoc.dv.catalog.install("fr-towns-by-dept", "neo4j", {
  type: "JDBC",
  url: "jdbc:postgresql:///communes?user=jb&password=jb",
  labels: ["Town","PopulatedPlace"],
  query: "SELECT code, name FROM towns where department = $dept_no",
  desc: "french towns by department number"
})

有关如何传递凭据以访问 RDB 的更多详细信息,请查看 Load JDBC 文档

查询虚拟化资源 (JDBC)

定义完成后,我们可以通过名称查询虚拟化资源,只需传递所需的参数。我们使用 apoc.dv.query 过程来执行此操作。它接受两个参数

  • 虚拟化资源的名称

  • 包含所需参数的映射 (map)。

CALL apoc.dv.query("fr-towns-by-dept", { dept_no: "73" })

查询返回一组通过运行虚拟化资源中定义的查询并使用 apoc.dv.query 调用中传递的参数按需生成的虚拟节点。

apoc.dv.jdbc query

通常,我们希望将此过程调用与 Neo4j 图中的数据结合起来。这是一个例子

WITH "Basse-Normandie" AS reg_name
MATCH (dep:Region { name: reg_name})-[:HAS_DEPT]->(d:Department)
CALL apoc.dv.query("fr-towns-by-dept",{dept_no: d.code}) YIELD node
RETURN node

我们甚至可以将 apoc.dv.query 返回的虚拟化节点链接到图中的真实节点,从而提供更丰富的查询结果。这就是 apoc.dv.queryAndLink 方法的目的。apoc.dv.queryAndLink 方法需要两个额外的参数:要链接虚拟节点的节点,以及用于链接的关系类型

MATCH (dep:Region { name: $regionName })-[hd:HAS_DEPT]->(d:Department)
CALL apoc.dv.queryAndLink(d,"HAS_TOWN", "fr-towns-by-dept",{ dept_no: d.code }) YIELD path
RETURN *

apoc.dv.queryAndLink 方法返回一个路径,该路径由作为第一个参数传递的节点,以及从虚拟化资源返回的虚拟节点和关系组成。

以下是在 Bloom 中使用上述查询的示例。代表给定部门中城镇的所有蓝色节点都是通过对上述查询使用搜索短语按需检索的虚拟节点。

apoc.dv.jdbc queryAndLink

关系的默认方向是传出(即 {direction: "OUT"}),但可以通过配置参数将其反转。示例

MATCH (hook:Hook) WITH hook
CALL apoc.dv.queryAndLink(hook, $relType, $name, $queryParams, { direction: "IN" }) yield path
RETURN path

列出虚拟化资源目录

apoc.dv.catalog.list 过程返回一个包含所有现有虚拟化资源及其描述的列表。它接受一个参数:即我们想要使用该资源的数据库名称(默认为 'neo4j')。

CALL apoc.dv.catalog.show()

从目录中删除虚拟化资源

当不再需要虚拟化资源时,可以使用 apoc.dv.catalog.remove 过程将其从目录中删除,并传递虚拟化资源的唯一名称作为参数。

CALL apoc.dv.catalog.drop("vr-name", <dbName>)

导出元数据

要在另一个数据库中导入 dv 目录(例如在执行 ./neo4j-admin backup/neo4j-admin restore 之后),请参阅 apoc.systemdb.export.metadata 过程。

通过 CSV 文件管理虚拟化资源

创建虚拟化资源 (CSV)

在 CSV 文件上定义虚拟化资源的过程与关系数据库的过程相同,除了查询参数 (query) 不同。

让我们想一个例子,我们在图中有一个产品目录,但关于产品还有一些额外信息,比如当前库存、单价、再订货水平,由于某种原因,这些信息保存在图之外的单独存储中(在本例中是一个文件)。我们将展示如何使用 apoc.dv 无缝结合这两部分信息。

让我们看另一个例子,我们通过 HTTP 定义一个 CSV 文件的虚拟化资源(类型:CSVurl: "http://data.neo4j.com/northwind/products.csv"),它将返回我们标记为 ProductDetails(labels: ["ProductDetails"])的节点。关于查询,没有像关系数据库那样的标准查询语言,所以我们使用类 Cypher 的表示法,使用 map 前缀来引用通过解析 CSV 文件返回的记录(query: "map.productID = $prod_id")。请注意,也可以使用 file:// 协议而不是 http:// 在本地访问该文件。

以下是创建此类虚拟化资源的 Cypher

CALL apoc.dv.catalog.install("prod-details-by-id", "neo4j", {
  type: "CSV",
  url: "http://data.neo4j.com/northwind/products.csv",
  labels: ["ProductDetails"],
  query: "map.productID = $prod_id",
  desc: "Product Details By ID"
})

查询虚拟化资源 (CSV)

与 JDBC 情况相同,我们可以通过名称查询虚拟化的 CSV 资源,只需传递所需的参数

CALL apoc.dv.query("prod-details-by-id", { prod_id: "3" })

在该示例中,查询返回一个通过解析虚拟化资源中定义的 CSV 文件,并应用查询参数中的表达式以及 apoc.dv.query 调用中传递的参数来过滤记录而按需生成的虚拟节点(显示返回的虚拟节点的表格视图)。

apoc.dv.csv query

将此过程调用与 Neo4j 图中的数据结合起来的示例

MATCH (p:Product { productName: "Northwoods Cranberry Sauce"})
CALL apoc.dv.query("prod-details-by-id",{ prod_id: p.productId }) YIELD node as details
RETURN p.productName as prodName,
  apoc.any.property(details, "unitsInStock") as unitsInStock,
  apoc.any.property(details, "reorderLevel") as reorderLevel,
  apoc.any.property(details, "quantityPerUnit") as quantityPerUnit,
  apoc.any.property(details, "unitPrice") as unitPrice

产生以下输出

apoc.dv.csv query integrated

在这种情况下,我们生成了一个表格结果,结合了图中的数据和从虚拟化 CSV 资源按需检索的数据。请注意,为了访问虚拟节点中的属性值,我们需要使用 apoc.any.property 函数。

如果我们希望查询返回的虚拟化节点链接到图中的真实节点,我们将使用 apoc.dv.queryAndLink 方法,如下所示

MATCH (p:Product { productName: "Northwoods Cranberry Sauce" })
CALL apoc.dv.queryAndLink(p, "HAS_DETAILS", "prod-details-by-id", { prod_id: p.productId }) YIELD path
RETURN *

在 Neo4j 浏览器中产生此输出

apoc.dv.csv queryAndLink
© . This site is unofficial and not affiliated with Neo4j, Inc.