このドキュメントでは、openCypher と Spanner Graph を次の方法で比較します。
- 用語
- データモデル
- スキーマ
- クエリ
- Mutation
このドキュメントは、openCypher v9 に精通していることを前提としています。
始める前に
Google Cloud コンソールを使用して Spanner Graph を設定しクエリを実行します。
用語
openCypher | Spanner Graph |
---|---|
ノード | ノード |
関係 | エッジ |
ノードラベル | ノードラベル |
関係タイプ | エッジラベル |
句 | Spanner Graph では、実行の完全な単位に statement という用語を使用し、ステートメントの修飾子に clause という用語を使用します。たとえば、 MATCH はステートメントですが、WHERE は句です。 |
関係の一意性 openCypher は、単一の一致においてエッジが重複する結果を返しません。 |
TRAIL パスSpanner Graph で一意のエッジが必要な場合は、 TRAIL モードを使用して、1 つの一致で一意のエッジを返します。 |
標準への準拠
Spanner Graph は、ISO Graph Query Language(GQL)と SQL/Property Graph Queries(SQL/PGQ)標準を採用しています。
データモデル
Spanner Graph と openCypher はどちらもプロパティ グラフ データモデルを採用していますが、いくつかの違いがあります。
openCypher | Spanner Graph |
---|---|
各関係には 1 つの関係タイプがあります。 |
ノードとエッジの両方に 1 つ以上のラベルがあります。 |
スキーマ
openCypher | Spanner Graph |
---|---|
グラフには定義済みスキーマがありません。 | グラフ スキーマは、CREATE PROPERTY GRAPH ステートメントを使用して明示的に定義する必要があります。ラベルはスキーマで静的に定義されます。ラベルを更新するには、スキーマを更新する必要があります。 詳細については、Spanner Graph スキーマを作成、更新、削除するをご覧ください。 |
クエリ
Spanner Graph のクエリ機能は openCypher の機能と類似しています。このセクションでは、Spanner Graph と openCypher の違いについて説明します。
グラフを指定する
openCypher には 1 つのデフォルト グラフがあり、クエリはデフォルト グラフに対して実行されます。Spanner Graph では複数のグラフを定義できます。クエリは GRAPH
句で始まり、クエリ対象のグラフを指定する必要があります。次に例を示します。
GRAPH FinGraph
MATCH (p:Person)
RETURN p.name
ORDER BY p.name
LIMIT 1;
詳細については、グラフクエリの構文をご覧ください。
グラフパターン マッチング
Spanner Graph は、openCypher と同様のグラフ パターン マッチング機能をサポートしています。違いについては、以降のセクションで説明します。
関係の一意性と TRAIL モード
openCypher は、単一の一致においてエッジが重複する結果を返しません。これは openCypher で「関係の一意性」と呼ばれます。Spanner Graph では、デフォルトで繰り返しエッジが返されます。一意性が必要である場合は、TRAIL
モードを使用して、単一の一致に重複するエッジが存在しないようにします。TRAIL
と他のパスモードの詳細なセマンティクスについては、パスモードをご覧ください。
次の例は、TRAIL
モードでクエリの結果がどのように変化するかを示しています。
- openCypher と Spanner Graph の
TRAIL
モードのクエリで想定される唯一のパスはt1
を 2 回繰り返すことであるため、空の結果を返します。 - デフォルトでは、Spanner Graph クエリは有効なパスを返します。
openCypher | Spanner Graph(TRAIL モード) | Spanner Graph(デフォルト モード) | ||||
---|---|---|---|---|---|---|
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 の変数長パターン マッチングは、Spanner Graph では「パスの定量化」と呼ばれます。パスの定量化では、次の例に示すように、異なる構文が使用されます。詳細については、定量化されたパスパターンをご覧ください。
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 Graph を使用すると、パスの定量化で使用される変数に直接アクセスできます。次の例では、Spanner Graph の 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 には、ノード間の最短パスを見つけるための 2 つの組み込み関数(shortestPath
と allShortestPath
)があります。
shortestPath
は、ノード間の単一の最短パスを見つけます。allShortestPath
は、ノード間のすべての最短パスを見つけます。同じ長さのパスが複数存在する場合があります。
Spanner Graph では、ノード間の単一の最短パスを見つけるために、別の構文(shortestPath.
の ANY SHORTEST
)を使用します。allShortestPath
関数は Spanner Graph ではサポートされていません。
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 では、複雑な式に明示的なエイリアシングが必要です。 |
|
サポート対象 |
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 では、オフセットと上限に定数式が必要です。 |
|
サポート対象 |
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 Graph でデータを挿入、更新、削除するをご覧ください。 |
データ型
Spanner Graph は、すべての GoogleSQL データ型をサポートしています。詳細については、GoogleSQL のデータ型をご覧ください。
以降のセクションでは、openCypher データ型と Spanner Graph データ型を比較します。
構造型
openCypher | Spanner Graph |
---|---|
ノード | ノード |
Edge | Edge |
パス | [Path] |
プロパティ型
openCypher | Spanner Graph |
---|---|
INT |
INT64 |
FLOAT |
FLOAT64 |
STRING |
STRING |
BOOLEAN |
BOOL |
LIST シンプルな型の同種のリスト。 たとえば、 INT のリスト、STRING のリストなど。1 つのリスト内で INT と STRING を混在させることはできません。 |
ARRAY |
複合タイプ
openCypher | Spanner Graph |
---|---|
LIST |
ARRAY または JSON |
MAP |
STRUCT または JSON |
Spanner Graph は、異なる型の異種リスト、動的キーリストのマップ、異種要素値型をサポートしていません。このようなユースケースには JSON を使用します。
型の強制変換
openCypher | Spanner Graph |
---|---|
INT -> FLOAT |
サポート対象 |
型変換ルールの詳細については、GoogleSQL の変換ルールをご覧ください。
関数と式
Spanner Graph は、グラフ関数と式に加えて、GoogleSQL の組み込み関数と式もすべてサポートしています。
このセクションでは、openCypher の関数と式、および Spanner Graph でこれらに対応する関数について説明します。
構造型の関数と式
型 | openCypher 関数または式 |
Spanner Graph 関数または式 |
|
---|---|---|---|
ノードとエッジ |
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 Graph 関数または式 |
|
---|---|---|---|
Scalar | 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 Graph は比較のチェーンをサポートしていません。これは、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 |
---|---|
CASE 式 | サポート対象 |
EXISTS サブクエリ | サポート対象 |
マップ投影 | サポートされていません。STRUCT 型は同様の機能を提供します。 |
リスト内包表記 | サポートされていません。GENERATE_ARRAY と ARRAY_TRANSFORM は、ほとんどのユースケースに対応しています。 |
クエリ パラメータ
次のクエリは、openCypher と Spanner Graph でのパラメータの使用方法の違いを示しています。
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 Graph データを挿入、更新、削除するをご覧ください。
ノードとエッジを作成する
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; |