面向 openCypher 用户的 Spanner 图参考

本文档在下面的部分中比较了 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;
      
结果为空 结果为空 结果:
src_id dst_id
16 20

以查询结果的形式返回图表元素

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 有两个内置函数可以查找节点之间的最短路径: shortestPathallShortestPath

  • 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...] 不受支持。
CREATEDELETESETREMOVEMERGE 如需了解详情,请参阅变更部分以及在 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 列表。
您不能在单个列表中混用 INTSTRING
ARRAY

复合类型

openCypher Spanner Graph
LIST ARRAYJSON
MAP STRUCTJSON

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 不受支持。
节点和边缘 .
property reference
.
[]
dynamic property reference
MATCH (n)
RETURN n[n.name]

不受支持。
将模式用作表达式 size(pattern) 不受支持。按以下方式使用子查询
VALUE {
  MATCH pattern
  RETURN COUNT(*) AS count;
}

属性类型函数和表达式

类型 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_SLICEARRAY_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
比较链
a < b < c

Spanner 图 不支持比较链。这相当于 与 AND 连接的比较运算。
例如:

      a < b AND b < C
      

布尔值 AND AND
OR OR
XOR
Spanner Graph 不支持 XOR。使用 <> 编写查询。

例如:
      boolean_1 <> boolean_2
      

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_ARRAYARRAY_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});

MATCH (p:Person {id: 100}), (a:Account {id: 1000}) CREATE (p)-[:Owns {create_time: timestamp()}]->(a);
INSERT INTO
Person (id, name)
VALUES (100, "John");

INSERT INTO Account (id, is_blocked) VALUES (1000, FALSE);
INSERT INTO PersonOwnAccount (id, account_id, create_time) VALUES (100, 1000, CURRENT_TIMESTAMP());
使用查询结果创建节点和边缘
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 CASCADEDELETE 会移除 (例如,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;

后续步骤