基于Cypher的视图

简介

基于 Cypher® 的视图是一种在 JDBC 客户端应用程序中创建虚拟视图的方式,这些视图由任意 Cypher 查询支持。它们允许您的 Neo4j 数据库以最佳方式利用,并利用所有 Cypher 结构,包括 JDBC 驱动程序可提供直接 SQL 到 Cypher 转换的所有结构。

基于 Cypher 的视图将出现在 JDBC 连接的数据库元数据中,并在客户端定义。它们包含

  • 一个名称

  • 一个 Cypher 查询

  • 列列表

名称必须是唯一的,并作为视图可查询的名称,以及出现在数据库元数据中的名称。只有枚举的列会出现在数据库元数据中。

要求

基于 Cypher 的视图需要启用SQL 转换,并且 classpath 中存在默认转换器,因此您必须在应用程序中添加相应的依赖项或使用完整包。如果您未能启用 SQL 转换或缺少标准转换器,您的基于 Cypher 的视图仍将加载,并贡献到数据库元数据中,但您无法查询它们。

虽然您可以在视图定义中使用任何有效的 Cypher 查询,但我们强烈建议不要使用对图进行更新的 Cypher 语句。我们不会解析 Cypher,也不会阻止像 MATCH (n) DETACH DELETE 这样随意删除您的图的 SELECT * 语句作为视图定义。但是,我们确实会阻止基于 Cypher 的视图用于 SQL 更新语句,例如 INSERTDELETEUPDATE

Cypher 查询基本上可以是任何形式,但它必须是 CALL {} 子查询中有效的查询。虽然我们可以直接执行查询,否则您将无法一次查询多个基于 Cypher 的视图。有关更多信息,请查看下面的“限制”。

配置和视图定义格式

基于 Cypher 的视图以 JSON 形式表示。其原生格式由以下模式定义

列表 1. 基于 Cypher 的视图的 JSON 模式
{
  "$schema": "https://json-schema.fullstack.org.cn/draft-07/schema#",
  "title": "JSON Schema for Cypher-backed views",
  "type": "array",
  "items": {
    "$ref": "#/$defs/viewType"
  },
  "$defs": {
    "viewType": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of this view."
        },
        "query": {
          "type": "string",
          "description": "Any valid Cypher query."
        },
        "columns": {
          "type": "array",
          "items": {
            "$ref": "#/$defs/columnType"
          }
        }
      },
      "required": [
        "name",
        "query",
        "columns"
      ],
      "title": "A view that will be queryable."
    },
    "columnType": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name as it will appear in the column list of the view."
        },
        "propertyName": {
          "type": "string",
          "description": "The property to pick from the graph, can be omitted when equal to the column name"
        },
        "type": {
          "type": "string",
          "description": "The Neo4j type of this column"
        }
      },
      "required": [
        "name",
        "type"
      ],
      "description": "A type representing a column in a relational view"
    }
  }
}

JDBC 驱动程序能够从以下位置加载资源:

  • 文件系统

  • 或通过 http(s)

并且资源必须通过名为 viewDefinitions 的连接属性进行配置。该属性可以作为查询参数添加到 JDBC URL 中,或作为 JDBC 属性。以下是一些将查询参数作为 JDBC URL 一部分的示例:

请注意,我们对文件 URI 方案中的斜杠数量有严格要求:file: 是协议,斜杠不属于协议本身。请使用一个斜杠 (/) 表示没有主机名,或使用三个斜杠 (///) 表示空主机名(实际效果相同)。我们不会猜测两个斜杠的含义,并且不支持使用主机名来读取文件。
jdbc:neo4j://localhost:7687?viewDefinitions=file:/my/views/foobar.json

这里视图定义位于同一机器上的 /my/views/ 文件夹中,文件名为 foobar.json

jdbc:neo4j://localhost:7687?viewDefinitions=file:///my/views/foobar.json

这与上面的 URL 等效

jdbc:neo4j://localhost:7687?viewDefinitions=https://myorg.com/movies.json

视图定义托管在安全 Web 服务器上

请确保仅从受信任的来源加载视图定义。如上所述,没有任何机制可以阻止将写入型 Cypher 查询用作视图定义,您也不希望它们从未知或不受信任的来源注入到您的应用程序中。

一个简单示例如下所示

列表 2. 返回所有电影及其演员的基于 Cypher 的视图。
[
  {
    "name": "v_movie_actors",
    "query": "MATCH (n:Movie)<-[:ACTED_IN]-(p:Person) RETURN elementId(n) AS id, n.title AS title, n.released AS released, collect(p.name) AS actors",
    "columns": [
      {
        "name": "id",
        "type": "STRING"
      },
      {
        "name": "title",
        "type": "STRING"
      },
      {
        "name": "released",
        "type": "INTEGER"
      },
      {
        "name": "actors",
        "type": "LIST"
      }
    ]
  }
]

在上述示例中,所有列都在 Cypher RETURN 子句中被投影,并通过 AS 命名,以匹配后续列列表中的列名。该视图可以如下方式查询,其中排序和谓词会下推到实际查询中

列表 3. 查询 v_movie_actors
SELECT * FROM v_movie_actors ORDER BY title

columnType 对象的 propertyName 属性可用于引用 Cypher 实体(节点或关系)的属性,如下例所示

列表 4. 定义一个使用虚拟列(id 函数)和 Cypher 查询返回的实体的视图
[
  {
    "name": "people",
    "query": "MATCH (n:Person) RETURN id(n) AS id, n",
    "columns": [
      {
        "name": "id",
        "type": "INTEGER"
      },
      {
        "name": "name",
        "propertyName": "n.name",
        "type": "STRING"
      }
    ]
  }
]

现在可以查询为

列表 5. 查询 v_people
SELECT * FROM v_people WHERE name LIKE 'A%' ORDER BY name

v_movie_actors 示例中的 ORDER BY 子句一样,谓词和排序子句将下推到传递给 Neo4j 数据库管理系统的实际 Cypher 中。

此外,我们支持与截至 2022 年 1 月的“Magnitude Simba Neo4j 商业智能工具数据连接器”1.0.10 版本相同的格式。但是,所有模式信息都将被忽略(模式名称以及视图是否隐藏)。

限制

基于 Cypher 的视图当然只能读取,不能修改(既不能更新也不能删除)。基于 Cypher 的视图不能与常规的“表”混合使用,即那些被视为标签然后进行匹配的表。如果您想同时查询多个基于 Cypher 的视图,您需要在 FROM 子句中列举它们,例如 view1, view2, view3,并酌情在 WHERE 子句中使用 view1.x = view2.y 这样的谓词进行连接。您不能使用 JOINLEFT OUTER 或任何其他 JOIN 子句,因为我们无法从基于 Cypher 的视图中推导出任何有意义的关系,而我们会在这些情况下尝试这样做。

这些限制应该不会有太大影响,因为您可以在构成视图的查询中表达任意复杂的表达式,以便您的 ETL 工具或任何其他程序可以利用 Cypher 的全部功能。