本文档在下面的部分中比较了 openCypher 和 Spanner Graph 方式:
- 术语
- 数据模型
- 架构
- 查询
- Mutation
本文档假定您熟悉 openCypher v9。
准备工作
使用 Google Cloud 控制台设置和查询 Spanner Graph。
术语
openCypher | Spanner Graph |
---|---|
节点 | 节点 |
关系 | 边缘 |
节点标签 | 节点标签 |
关系类型 | 边缘标签 |
子句 | Spanner Graph 使用术语 statement 来表示完整的执行单元,使用 clause 来表示语句修饰符。例如, MATCH 是一个语句,而
WHERE 是一个子句。 |
关系唯一性 openCypher 不会在单个匹配中返回包含重复边的结果。 |
TRAIL 路径如果希望在 Spanner 图中实现唯一性,请使用 TRAIL 模式,以便在单次匹配中返回唯一边。 |
标准合规性
Spanner Graph 采用 ISO 图查询语言 (GQL) 和 SQL/属性图查询 (SQL/PGQ) 标准。
数据模型
Spanner Graph 和 openCypher 都采用了属性图数据模型,但存在一些差异。
openCypher | Spanner Graph |
---|---|
每种关系都有且仅有一个关系类型。 |
节点和边缘都有一个或多个标签。 |
架构
openCypher | Spanner Graph |
---|---|
图表没有预定义的架构。 | 必须使用
CREATE PROPERTY GRAPH 语句。标签在架构中静态定义。要更新标签,您需要 您需要更新架构 如需了解详情,请参阅创建、更新或删除 Spanner 图架构。 |
查询
Spanner Graph 查询功能与 openCypher 的查询功能类似。Spanner Graph 与 openCypher 之间的区别如下 部分。
指定图表
在 openCypher 中,只有一个默认图,查询会在默认图上运行。在 Spanner Graph 中,您可以定义多个图表,并且查询必须以 GRAPH
子句开头,以指定要查询的图表。例如:
GRAPH FinGraph
MATCH (p:Person)
RETURN p.name
ORDER BY p.name
LIMIT 1;
如需了解详情,请参阅图表查询语法。
图表模式匹配
Spanner Graph 支持类似于 openCypher 的图模式匹配功能。以下各部分介绍了这些差异。
关系唯一性和 TRAIL 模式
openCypher 不会在单个匹配中返回包含重复边的结果;这在 openCypher 中称为关系唯一性。在 Spanner 图中,默认会返回重复边。如果需要唯一性,请使用
TRAIL
模式,以确保单个匹配中不存在重复边缘。对于
TRAIL
和其他不同路径模式的详细语义,请参阅
路径模式。
以下示例展示了查询结果如何随 TRAIL
模式而变化:
- openCypher 和 Spanner Graph
TRAIL
模式查询返回空值 结果,因为唯一可能的路径是重复t1
两次。 - 默认情况下,Spanner Graph 查询会返回一个有效路径。
openCypher | Spanner Graph(TRAIL 模式) | Spanner 图(默认模式) | ||||
---|---|---|---|---|---|---|
MATCH (src:Account)-[t1:Transfers]-> (dst:Account)-[t2:Transfers]-> (src)-[t1]->(dst) WHERE src.id = 16 RETURN src.id AS src_id, dst.id AS dst_id; |
GRAPH FinGraph MATCH TRAIL (src:Account)-[t1:Transfers]-> (dst:Account)-[t2:Transfers]-> (src)-[t1]->(dst) WHERE src.id = 16 RETURN src.id AS src_id, dst.id AS dst_id; |
GRAPH FinGraph MATCH (src:Account)-[t1:Transfers]-> (dst:Account)-[t2:Transfers]-> (src)-[t1]-> (dst) WHERE src.id = 16 RETURN src.id AS src_id, dst.id AS dst_id; |
||||
结果为空。 | 结果为空。 | 结果:
|
以查询结果的形式返回图表元素
openCypher | Spanner Graph |
---|---|
MATCH (account:Account) WHERE account.id = 16; RETURN account; |
GRAPH FinGraph MATCH (account:Account) WHERE account.id = 16; RETURN TO_JSON(account) AS account; |
在 Spanner Graph 中,查询结果不会返回图元素。使用 TO_JSON
函数以 JSON 格式返回图表元素。
可变长度模式匹配和模式量化
openCypher 中的可变长度模式匹配称为路径量化 。路径量化使用不同的语法,如以下示例所示。如需了解详情,请参阅量化路径模式。
openCypher | Spanner Graph |
---|---|
MATCH (src:Account)-[:Transfers*1..2]->(dst:Account) WHERE src.id = 16 RETURN dst.id ORDER BY dst.id; |
GRAPH FinGraph MATCH (src:Account)-[:Transfers]->{1,2}(dst:Account) WHERE src.id = 16 RETURN dst.id ORDER BY dst.id; |
长度可变的模式:元素列表
借助 Spanner 图,您可以直接访问路径量化中使用的变量。在以下示例中,Spanner 图中的 e
没有变化。
在 openCypher 中以 edges(p)
的形式指定。
openCypher | Spanner Graph |
---|---|
MATCH p=(src:Account)-[:Transfers*1..3]->(dst:Account) WHERE src.id = 16 RETURN edges(p); |
GRAPH FinGraph MATCH (src:Account) -[e:Transfers]->{1,3} (dst:Account) WHERE src.id = 16 RETURN TO_JSON(e) AS e; |
最短路径
openCypher 有两个内置函数可以查找节点之间的最短路径:
shortestPath
和allShortestPath
。
shortestPath
查找节点之间的单个最短路径。allShortestPath
查找节点之间的所有最短路径。可以有多个长度相同的路径。
Spanner 图使用其他语法查找单个最短路径
ANY SHORTEST
表示 shortestPath.
allShortestPath
函数。
openCypher | Spanner Graph |
---|---|
MATCH (src:Account {id: 7}), (dst:Account {id: 20}), p = shortestPath((src)-[*1..10]->(dst)) RETURN length(p) AS path_length; |
GRAPH FinGraph MATCH ANY SHORTEST (src:Account {id: 7})-[e:Transfers]->{1, 3} (dst:Account {id: 20}) RETURN ARRAY_LENGTH(e) AS path_length; |
语句和子句
下表列出了 openCypher 子句,并指出了这些子句是否 它们在 Spanner Graph 中受支持。
openCypher | Spanner Graph | |
---|---|---|
MATCH |
支持。如需了解详情,请参阅图表模式匹配。 | |
OPTIONAL MATCH |
支持。如需了解详情,请参阅图模式匹配。 | |
RETURN / WITH |
支持。如需了解详情,请参阅 RETURN 语句和 WITH 语句。对于复杂的表达式,Spanner 图需要显式重用。 |
|
支持。 |
GRAPH FinGraph MATCH (p:Person) RETURN EXTRACT(YEAR FROM p.birthday) AS birthYear; |
|
不受支持。 |
GRAPH FinGraph MATCH (p:Person) RETURN EXTRACT(YEAR FROM p.birthday); -- No aliasing |
|
WHERE |
支持。如需了解详情,请参阅图表模式的定义。 | |
ORDER BY |
支持。有关详情,请参阅
ORDER BY 语句。 |
|
SKIP / LIMIT |
支持。如需了解详情,请参阅 SKIP 语句和 LIMIT 语句。Spanner 图需要为偏移量和上限使用常量表达式。 |
|
支持。 |
GRAPH FinGraph MATCH (n:Account) RETURN n.id SKIP @offsetParameter LIMIT 3; |
|
不支持。 |
GRAPH FinGraph MATCH (n:Account) RETURN n.id LIMIT VALUE { MATCH (m:Person) RETURN COUNT(*) AS count } AS count; -- Not a constant expression |
|
UNION |
支持。如需了解详情,请参阅复合图表查询。 | |
UNION ALL |
支持。如需了解详情,请参阅复合图查询。 | |
UNWIND |
受 FOR 语句支持。 |
|
GRAPH FinGraph LET arr = [1, 2, 3] FOR num IN arr RETURN num; |
||
MANDATORY MATCH |
不受支持。 | |
CALL[YIELD...] |
不受支持。 | |
CREATE 、DELETE 、SET 、REMOVE 、MERGE |
如需了解详情,请参阅变更部分以及在 Spanner 图中插入、更新或删除数据。 |
数据类型
Spanner Graph 支持所有 GoogleSQL 数据类型。如需了解详情,请参阅 GoogleSQL 中的数据类型。
以下部分将 openCypher 数据类型与 Spanner 图数据类型进行比较。
结构类型
openCypher | Spanner Graph |
---|---|
节点 | 节点 |
Edge | 边缘 |
路径 | 不受支持。 |
属性类型
openCypher | Spanner Graph |
---|---|
INT |
INT64 |
FLOAT |
FLOAT64 |
STRING |
STRING |
BOOLEAN |
BOOL |
LIST () 简单类型的同构列表。 例如, INT 列表、STRING 列表。您不能在单个列表中混用 INT 和 STRING 。 |
ARRAY |
复合类型
openCypher | Spanner Graph |
---|---|
LIST |
ARRAY 或 JSON |
MAP |
STRUCT 或 JSON |
Spanner Graph 不支持不同类型的异构列表,也不支持动态键列表和异构元素值类型的映射。请针对这些用例使用 JSON。
类型强制转换
openCypher | Spanner Graph |
---|---|
INT -> FLOAT |
受支持。 |
如需详细了解类型转换规则,请参阅 GoogleSQL 中的转换规则。
函数和表达式
除了图函数和表达式之外,Spanner Graph 还支持所有 GoogleSQL 内置函数和表达式。
如需查看函数和表达式的完整列表,请参阅 GoogleSQL 函数、运算符和条件。
本部分列出了 openCypher 函数和表达式及其在 Spanner Graph 中的等效项。
结构体类型函数和表达式
类型 | openCypher 函数或表达式 |
Spanner 图 函数或表达式 |
|
---|---|---|---|
节点和边缘 |
exists(n.prop) |
PROPERTY_EXISTS(n, prop) |
|
id (返回整数) |
不受支持。 | ||
properties |
TO_JSON |
||
keys (属性类型名称,但不是属性值) |
PROPERTY_NAMES |
||
labels |
LABELS |
||
Edge | endNode |
不受支持。 | |
startNode |
不受支持。 | ||
type |
LABELS |
||
路径 | length |
不受支持。 | |
nodes |
不受支持。 | ||
relationships |
不受支持。 | ||
节点和边缘 | .
|
. |
|
[]
|
不受支持。 | ||
将模式用作表达式 | size(pattern) |
不受支持。按以下方式使用子查询
|
属性类型函数和表达式
类型 | openCypher 函数或表达式 |
Spanner 图 函数或表达式 |
|
---|---|---|---|
标量 | coalesce |
COALESCE |
|
head |
ARRAY_FIRST |
||
last |
ARRAY_LAST |
||
size(list) |
ARRAY_LENGTH |
||
size(string) |
LENGTH |
||
timestamp |
UNIX_MILLIS(CURRENT_TIMESTAMP()) |
||
toBoolean /toFloat /toInteger |
CAST(expr AS type) |
||
汇总 | avg |
AVG |
|
collect |
ARRAY_AGG |
||
count
| COUNT |
||
max |
MAX |
||
min |
MIN |
||
percentileCont |
PERCENTILE_CONT |
||
percentileDisc |
PERCENTILE_DISC |
||
stDev |
STDDEV |
||
stDevP |
不受支持。 | ||
sum |
SUM |
||
列出 | range |
GENERATE_ARRAY |
|
reverse |
ARRAY_REVERSE |
||
tail |
Spanner Graph 不支持 tail 。请改用 ARRAY_SLICE 和 ARRAY_LENGTH 。 |
||
数学符号 | abs |
ABS |
|
ceil |
CEIL |
||
floor |
FLOOR |
||
rand |
RAND |
||
round |
ROUND |
||
sign |
SIGN |
||
e |
EXP(1) |
||
exp |
EXP |
||
log |
LOG |
||
log10 |
LOG10 |
||
sqrt |
SQRT |
||
acos |
ACOS |
||
asin |
ASIN |
||
atan |
ATAN |
||
atan2 |
ATAN2 |
||
cos |
COS |
||
cot |
COT |
||
degrees |
r * 90 / ASIN(1) |
||
pi |
ACOS(-1) |
||
radians |
d * ASIN(1) / 90 |
||
sin |
SIN |
||
tan |
TAN |
||
字符串 | left |
LEFT |
|
ltrim |
LTRIM |
||
replace |
REPLACE |
||
reverse |
REVERSE |
||
right |
RIGHT |
||
rtrim |
RTRIM |
||
split |
SPLIT |
||
substring |
SUBSTR |
||
tolower |
LOWER |
||
tostring |
CAST(expr AS STRING) |
||
toupper |
UPPER |
||
trim |
TRIM |
||
DISTINCT | DISTINCT |
DISTINCT |
|
数学 | + |
+ |
|
- |
- |
||
* |
* |
||
/ |
/ |
||
% |
MOD |
||
^ |
POW |
||
比较 | = |
= |
|
<> |
<> |
||
< |
< |
||
> |
> |
||
<= |
<= |
||
>= |
>= |
||
IS [NOT] NULL |
IS [NOT] NULL |
||
比较链
|
Spanner 图
不支持比较链。这相当于
与 AND 连接的比较运算。例如:
|
||
布尔值 | AND |
AND |
|
OR |
OR |
||
XOR |
Spanner Graph 不支持 XOR 。使用 <> 编写查询。例如:
|
||
NOT |
NOT |
||
字符串 | STARTS WITH |
STARTS_WITH |
|
ENDS WITH |
ENDS_WITH |
||
CONTAINS |
REGEXP_CONTAINS |
||
+ |
CONCAT |
||
列出 | + |
ARRAY_CONCAT |
|
IN |
ARRAY_INCLUDES |
||
[] |
[] |
其他表达式
openCypher | Spanner Graph |
---|---|
大小写表达式 | 受支持。 |
Exists 子查询 | 受支持。 |
地图投影 | 不受支持。STRUCT 类型提供类似的功能。 |
列表推理 | 不受支持。GENERATE_ARRAY 和 ARRAY_TRANSFORM 涵盖了大多数用例。 |
查询参数
以下查询展示了在 openCypher 和 Spanner 图中使用参数的区别。
openCypher | Spanner Graph | |
---|---|---|
参数 | MATCH (n:Person) WHERE n.id = $id RETURN n.name; |
GRAPH FinGraph MATCH (n:Person) WHERE n.id = @id RETURN n.name; |
Mutation
Spanner Graph 使用 GoogleSQL DML 来更改节点和边输入表。如需了解详情,请参阅 插入、更新或删除 Spanner 图谱数据。
创建节点和边缘
openCypher | Spanner Graph | |
---|---|---|
创建节点和边缘 | CREATE (:Person {id: 100, name: 'John'}); CREATE (:Account {id: 1000, is_blocked: FALSE}); |
INSERT INTO Person (id, name) VALUES (100, "John"); |
使用查询结果创建节点和边缘 |
MATCH (a:Account {id: 1}), (oa:Account) WHERE oa <> a CREATE (a)-[:Transfers {amount: 100, create_time: timestamp()}]->(oa); |
INSERT INTO AccountTransferAccount(id, to_id, create_time, amount) SELECT a.id, oa.id, CURRENT_TIMESTAMP(), 100 FROM GRAPH_TABLE( FinGraph MATCH (a:Account {id:1000}), (oa:Account) WHERE oa <> a ); |
在 Spanner Graph 中,标签根据
CREATE PROPERTY GRAPH
DDL 语句。
更新节点和边
openCypher | Spanner Graph | |
---|---|---|
更新属性 | MATCH (p:Person {id: 100}) SET p.country = 'United States'; |
UPDATE Person AS p SET p.country = 'United States' WHERE p.id = 100; |
如需更新 Spanner Graph 标签,请参阅创建、更新或删除 Spanner Graph 架构。
合并节点和边缘
openCypher | Spanner Graph | |
---|---|---|
插入新元素或更新属性 | MERGE (p:Person {id: 100, country: 'United States'}); |
INSERT OR UPDATE INTO Person (id, country) VALUES (100, 'United States'); |
删除节点和边缘
删除边缘与删除输入表相同。
openCypher | Spanner Graph | |
---|---|---|
删除节点和边缘 | MATCH (p:Person {id:100}), (a:Account {id:1000}) DELETE (p)-[:Owns]->(a); |
DELETE PersonOwnAccount WHERE id = 100 AND account_id = 1000; |
删除节点需要处理可能存在的悬空边。如果指定了 DELETE CASCADE
,DELETE
会移除
(例如,openCypher 中的 DETACH DELETE
)。如需了解详情,请参阅 Spanner 架构概览。
openCypher | Spanner Graph | |
---|---|---|
删除节点和关联的边 | DETACH DELETE (:Account {id: 1000}); |
DELETE Account WHERE id = 1000; |
返回更改结果
openCypher | Spanner Graph | |
---|---|---|
在插入或更新后返回结果 | MATCH (p:Person {id: 100}) SET p.country = 'United States' RETURN p.id, p.name; |
UPDATE Person AS p SET p.country = 'United States' WHERE p.id = 100 THEN RETURN id, name; |
删除后返回结果 | DELETE (p:Person {id: 100}) RETURN p.country; |
DELETE FROM Person WHERE id = 100 THEN RETURN country; |