基于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 更新语句,例如 INSERT 、DELETE 或 UPDATE 。 |
Cypher 查询基本上可以是任何形式,但它必须是 CALL {}
子查询中有效的查询。虽然我们可以直接执行查询,否则您将无法一次查询多个基于 Cypher 的视图。有关更多信息,请查看下面的“限制”。
配置和视图定义格式
基于 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 查询用作视图定义,您也不希望它们从未知或不受信任的来源注入到您的应用程序中。 |
一个简单示例如下所示
[
{
"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
命名,以匹配后续列列表中的列名。该视图可以如下方式查询,其中排序和谓词会下推到实际查询中
v_movie_actors
SELECT * FROM v_movie_actors ORDER BY title
columnType
对象的 propertyName
属性可用于引用 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"
}
]
}
]
现在可以查询为
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
这样的谓词进行连接。您不能使用 JOIN
、LEFT OUTER
或任何其他 JOIN
子句,因为我们无法从基于 Cypher 的视图中推导出任何有意义的关系,而我们会在这些情况下尝试这样做。
这些限制应该不会有太大影响,因为您可以在构成视图的查询中表达任意复杂的表达式,以便您的 ETL 工具或任何其他程序可以利用 Cypher 的全部功能。