このドキュメントでは、openCypher と Spanner Graph を次の方法で比較します。
- 用語
 - データモデル
 - スキーマ
 - クエリ
 - ミューテーション
 
このドキュメントは、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 / プロパティ グラフ クエリ(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;
詳細については、グラフクエリの構文をご覧ください。
グラフパターン マッチング
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 | 
|---|---|
| ノード | ノード | 
| エッジ | エッジ | 
| パス | パス | 
プロパティ型
| 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 | 
    ||
| エッジ | endNode | 
      サポートされていません。 | |
startNode | 
      サポートされていません。 | ||
type | 
      LABELS | 
    ||
| パス | length | 
      サポートされていません。 | |
nodes | 
      サポートされていません。 | ||
relationships | 
      サポートされていません。 | ||
| ノードとエッジ | .
 | 
      . | 
    |
[]
 | 
      サポートされていません。 | ||
| 式としてのパターン | size(pattern) | 
      サポートされていません。次のようにサブクエリを使用します。
  | 
    
プロパティ タイプの関数と式
| タイプ | openCypher 関数または式  | 
      Spanner Graph 関数または式  | 
    |
|---|---|---|---|
| スカラー | 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;  | 
    
ミューテーション
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;  |