基于 Cypher 的视图
简介
Cypher®-backed 视图是一种在 JDBC 客户端应用程序内部创建虚拟视图的方式,这些视图由任意 Cypher 查询支持。它们能够让您的 Neo4j 数据库以最佳方式被利用,并使用所有 Cypher 构造,包括 JDBC 驱动能够提供直接 SQL 到 Cypher 转换的所有内容。
基于 Cypher 的视图将出现在 JDBC 连接的数据库元数据中,并在客户端侧定义。它们由以下部分组成
-
名称
-
Cypher 查询
-
列列表
名称必须唯一,并且将作为可查询的视图名称出现在数据库元数据中。仅列出的列会出现在数据库元数据中。
要求
基于 Cypher 的视图需要启用 SQL 翻译,并在类路径上拥有 默认翻译器,因此必须在应用程序中添加相应的依赖或使用 完整捆绑包。如果未启用 SQL 翻译或缺少标准翻译器,Cypher‑backed 视图仍会被加载并出现在数据库元数据中,但无法对其进行查询。
虽然您可以在视图定义中使用任何有效的 Cypher 查询,但我们强烈建议不要使用对图进行更新的 Cypher 语句。我们并不解析 Cypher,也不会阻止类似 SELECT * 的语句在视图定义中随意使用 MATCH (n) DETACH DELETE 删除图。但我们会阻止基于 Cypher 的视图用于 SQL 更新语句,例如 INSERT、DELETE 或 UPDATE。 |
Cypher 查询基本上可以是任意形状,但它必须是能够在 CALL {} 子查询中有效的查询。虽然我们可以直接执行该查询,但否则您将无法一次查询多个基于 Cypher 的视图。更多信息请查看下面的 “限制”。
配置和视图定义格式
基于 Cypher 的视图以 JSON 表示。原生格式由下面的 模式 定义
{
"$schema": "https://schema.json.js.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://:7687?viewDefinitions=file:/my/views/foobar.json-
这里的视图定义位于同一机器的文件夹
/my/views/,文件名为foobar.json jdbc:neo4j://:7687?viewDefinitions=file:///my/views/foobar.json-
这等同于上面的 URL
jdbc:neo4j://:7687?viewDefinitions=https://myorg.com/movies.json-
在安全网页服务器上托管的视图定义
| 请确保仅从受信任的来源加载视图定义。如上所述,没有任何机制阻止将编写的 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_actorsSELECT * 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_peopleSELECT * FROM v_people WHERE name LIKE 'A%' ORDER BY name
正如在 v_movie_actors 示例中的 ORDER BY 子句一样,谓词和排序子句将下推到传递给 Neo4j DBMS 的实际 Cypher 中。
另外,我们支持与 “Magnitude Simba Neo4j 数据连接器(用于商业智能工具)” 1.0.10 版(截至 2022 年 1 月)相同的格式。不过所有的模式信息将被忽略(模式名称以及视图是否隐藏)。
限制
基于 Cypher 的视图当然只能读取,不能修改(既不能更新也不能删除)。基于 Cypher 的视图不能与常规“表”混用,即那些被视为标签并随后进行匹配的表。如果想一次查询多个基于 Cypher 的视图,需要在 FROM 子句中枚举它们,例如 view1, view2, view3,并在 WHERE 子句中使用类似 view1.x = view2.y 的谓词进行适当的连接。不能使用 JOIN、LEFT OUTER 或任何其他 JOIN 子句,因为我们无法从基于 Cypher 的视图中推导出任何有意义的关系,这在此类情况下是我们尝试的内容。
这些限制其实影响不大,因为您可以在构成视图的查询中表达任意复杂的表达式,从而使您的 ETL 工具或其他任何程序都能充分利用 Cypher 的全部功能。