Spanner Graph のトラブルシューティング

このドキュメントでは、Spanner Graph の使用時に発生する可能性のあるエラーについて説明します。エラーの例と推奨の対応方法も記載しています。

このトラブルシューティング ガイドを参照したうえでなおサポートが必要な場合は、サポートの利用をご覧ください。

スキーマエラー

スキーマの結果は、Spanner Graph を設定してクエリを実行するで使用したデータセットに基づいています。

要素キーは一意である必要がある

エラー メッセージ

Neither the primary keys nor any unique index defined on the property graph element source table `Person` provides the uniqueness guarantee for graph element `Person` belonging to the graph `FinGraph`. You want to redefine the element key columns (`name`) based on the source table's primary keys, or create a unique index on the element's key columns.

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person KEY (name)
  );

要素キー列に一意のインデックスを作成し、ソーステーブルの主キーに基づいて要素キー列を再定義します。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person KEY (id)
  );

または、要素キー列に一意のインデックスを作成します。

CREATE UNIQUE INDEX PersonNameIndex ON Person(name);
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person KEY (name)
  );

要素定義の名前は一意である必要がある

エラー メッセージ

Account is defined more than once; use a unique name.

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Account,
    Person
  )
  EDGE TABLES (
    Account
      SOURCE KEY(owner_id) REFERENCES Person
      DESTINATION KEY(account_id) REFERENCES Account
  );

エッジ定義に一意の名前を使用します。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Account,
    Person
  )
  EDGE TABLES (
    Account AS Owns
      SOURCE KEY(owner_id) REFERENCES Person
      DESTINATION KEY(account_id) REFERENCES Account
  );

ラベル定義はプロパティで一貫している必要がある

エラー メッセージ

The label Entity is defined with different property declarations. There is one instance of this label defined with properties of [id]. Another instance is defined with properties of [name].

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person LABEL Entity PROPERTIES (name),
    Account LABEL Entity PROPERTIES (id)
  );

同じラベルで同じプロパティ名のセットを使用する必要があります。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person LABEL Entity PROPERTIES (id, name),
    Account LABEL Entity PROPERTIES (id, name)
  );

プロパティ宣言はプロパティ型で一貫している必要がある

エラー メッセージ

The property declaration of name has type conflicts. There is an existing declaration of type INT64. There is a conflicting one of type STRING.

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person PROPERTIES (name),
    Account PROPERTIES (id AS name)
  );
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person PROPERTIES (name),
    Account PROPERTIES (CAST(id AS STRING) AS name)
  );

プロパティの定義がサブクエリではない

エラー メッセージ

Property value expression of count cannot contain a subquery.

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person PROPERTIES ((SELECT COUNT(*) FROM Person) AS count)
  );

なし。この条件は許可されません。

プロパティの定義は同じ要素定義内で一貫している必要がある

エラー メッセージ

Property location has more than one definition in the element table Person

エラーの例

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person
      LABEL Person PROPERTIES (country AS location)
      LABEL Entity PROPERTIES (city AS location)
  );

同じプロパティ定義を使用します。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person
      LABEL Person PROPERTIES (country AS location)
      LABEL Entity PROPERTIES (country AS location)
  );

または、別のプロパティ名を割り当てます。

CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (
    Person
      LABEL Person PROPERTIES (country AS location)
      LABEL Entity PROPERTIES (city AS city)
  );

クエリエラー

クエリ結果は、Spanner Graph の設定とクエリで使用するデータセットに基づいています。

グラフ要素をクエリ結果として返すことはできない

エラー メッセージ

Returning expressions of type GRAPH_ELEMENT is not allowed

エラーの例

GRAPH FinGraph
MATCH (n:Account)
RETURN n;
GRAPH FinGraph
MATCH (n:Account)
RETURN TO_JSON(n) AS n;

プロパティの指定を WHERE 句で使用できない

エラー メッセージ

WHERE clause cannot be used together with property specification

エラーの例

GRAPH FinGraph
MATCH (n:Account {id: 1} WHERE n.is_blocked)
RETURN n.id;

以下にある推奨の対応方法のいずれかを実施してください。

GRAPH FinGraph
MATCH (n:Account {id: 1})
WHERE n.is_blocked
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account WHERE n.id = 1 AND n.is_blocked )
RETURN n.id;
GRAPH FinGraph
MATCH (n:Account {id: 1, is_blocked: TRUE})
RETURN n.id;

前のステートメントで定義された変数への参照が許可されない

エラー メッセージ

Name 'account_id', defined in the previous statement, can only be referenced in the outermost WHERE clause of MATCH

説明

MATCH パターン内では、前のステートメントで定義された変数への参照は許可されません。グラフクエリでは、前のステートメントで定義された名前は、MATCH の最も外側の WHERE 句でのみ使用できます。

エラーの例
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account {id: account_id})
RETURN n.id;
GRAPH FinGraph
LET account_id = 1
MATCH (n:Account)
WHERE n.id = account_id
RETURN n.id;

相関グラフ変数の再定義は許可されない

エラー メッセージ

The name account is already defined; redefining graph element variables in a subquery is not allowed. To refer to the same graph element, use a different name and add an explicit filter that checks for equality.

説明

グラフクエリでは、内部グラフのサブクエリでグラフ要素名を再定義することはできません。このシナリオは、外側のスコープと同じグラフ要素を参照している、または外側のスコープ名をシャドウする新しいグラフ要素にバインドされていると解釈される可能性があります。再定義は許可されません。

エラーの例

GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
  MATCH (account:Account)-[transfer:Transfers]->(:Account)
  RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;
GRAPH FinGraph
MATCH (account:Account)
RETURN account.id AS account_id, VALUE {
  MATCH (a:Account)-[transfer:Transfers]->(:Account)
  WHERE a = account
  RETURN SUM(transfer.amount) AS total_transfer
} AS total_transfer;

クエリのセマンティクスに関する問題

クエリ結果は、Spanner Graph の設定とクエリで使用するデータセットに基づいています。

WHEREFILTER が異なると、出力結果も異なります

説明

FILTER はステートメントです。一方、WHERE は句で、MATCH ステートメントや OPTIONAL MATCH ステートメントの一部として使われます。

最初の例では、WHERE 句は OPTIONAL MATCH ステートメントで指定されたパターンに追加の制約を加えます。これは、照合が完了した後にフィルタするという意味ではありません。

2 番目の例では、FILTER ステートメントは、照合が完了した後に絞り込むためのフィルタです。

問題の例

次の例では、WHEREFILTER が異なるため、出力結果が異なります。

例 1

GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
WHERE FALSE
RETURN n.id AS n_id, m.id AS m_id;
n_id m_id
7 null

例 2

GRAPH FinGraph
MATCH (n:Account {id: 7})
OPTIONAL MATCH (m:Account)
FILTER FALSE
RETURN n.id AS n_id, m.id AS m_id;

空の結果。

異なる変数がステートメント間で引き継がれると、出力も異なってくる

説明

グラフクエリ言語では、同じ変数が複数回宣言されても、それはすべて同じグラフ要素を指します。

例 1 では、id7 であり 16 でもあるような Account ノードは存在しません。その結果、空の結果が返されます。

例 2 では、n は前のステートメントから返っていません(id のみが返されています)。そのため、2 番目の MATCH では、id16Account ノードが探されます。

問題の例

次の例では、ステートメント間で異なる変数が受け渡されているため、出力結果が異なります。

例 1

GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n

NEXT

MATCH (n:Account {id: 16})
RETURN n.id AS n_id;

空の結果。

例 2

GRAPH FinGraph
MATCH (n:Account {id: 7})
RETURN n.id AS id

NEXT

MATCH (n:Account {id: 16})
RETURN n.id AS n_id;
n_id
16

LIMIT 以外のステートメントが続く場合、ORDER BY が無視される

説明

グラフクエリ言語では、次のいずれかに該当する場合を除き、ORDER BY ステートメントは無視されます。

  • ORDER BY が最後のステートメントである。
  • ORDER BY の直後に LIMIT が続く。

例 1 では、LIMITORDER BY の直後に続かず、最後の LIMIT は分離されています。そのため、ORDER BY はエンジンで無視されます。

例 2 では、ORDER BY の直後に LIMIT があるため、ORDER BY が適用されます。

問題の例

次の例では、出力結果が異なります。これは、例 1 で ORDER BYLIMIT と一緒に使われていないため無視されるからです。

例 1

GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
RETURN n.id
LIMIT 3;
n_id
7

例 2

GRAPH FinGraph
MATCH (n:Account)
ORDER BY n.id DESC
LIMIT 3
RETURN n.id;
n_id
20

エッジパターンが異なると出力結果も異なる

説明

エラーの例で使用されているデータセットでは、ANY 方向のエッジパターンがグラフ内の各 Transfers エッジに対して 2 回ずつ照合されます。

例 1 では、Account(id=x) から Account(id=y) への Transfers エッジは、次のように 2 回照合できます。

  • n= Account(id=x)、m= Account(id=y)
  • n= Account(id=y)、m= Account(id=x)

例 2 では、n=Account(id=x) かつ m=Account(id=y) となる、1 つだけの一致が存在します。

結果として、例 1 のクエリは 10 を返し、例 2 のクエリは 5 を返します。

問題の例

次の例では、異なるエッジパターンが使用されているため、出力結果が異なります。

例 1

GRAPH FinGraph
MATCH (n:Account)-[:Transfers]-(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
num_transfer_edges
10

例 2

GRAPH FinGraph
MATCH (n:Account)-[:Transfers]->(m:Account)
RETURN COUNT(*) AS num_transfer_edges;
num_transfer_edges
5

ミューテーション エラー

ミューテーションの結果は、Spanner Graph を設定してクエリを実行するで使用したデータセットに基づいています。

ソースノードが存在しないため外部キー制約に違反する

エラー メッセージ

Parent row for row [...] in table AccountTransferAccount is missing. Row cannot be written.

説明

AccountTransferAccount エッジテーブルは INTERLEAVED INTO PARENT Account node テーブルです。Transfer エッジを作成するには、親の Account ノードがすでに存在している必要があります。

エラーの例

INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (100, 1, PENDING_COMMIT_TIMESTAMP(), 200);

まず先頭の Account ノードを作成し、次に Transfer エッジを作成します。

宛先ノードが存在しないため外部キー制約に違反する

エラー メッセージ

Foreign key constraint FK_TransferTo is violated on table AccountTransferAccount. Cannot find referenced values in Account(id)

説明

AccountTransferAccount テーブルは、FK_TransferTo という ForeignKey を通じて Accounttable を参照しています。Transfer エッジを作成するには、参照される Account ノード(後ろ側のノード)がすでに存在している必要があります。

エラーの例

INSERT INTO AccountTransferAccount (id, to_id, create_time, amount)
VALUES (1, 100, PENDING_COMMIT_TIMESTAMP(), 200);

最初に末尾の Account ノードを作成し、次に Transfer エッジを作成します。

孤立した出力方向のエッジが親子関係に違反している

エラー メッセージ

Integrity constraint violation during DELETE/REPLACE. Found child row [...] in table AccountTransferAccount

説明

AccountTransferAccount エッジテーブルは INTERLEAVED INTO PARENT Account ノードテーブルであり、削除する Account ノードには出力方向のエッジがまだ接続されています。

エラーの例

DELETE FROM Account WHERE id = 1;

まず、出力方向の Transfer エッジをすべて削除してから、Account ノードを削除します。または、INTERLEAVEON DELETE CASCADE を定義し、Spanner でエッジを自動的に削除します。

孤立した入力方向のエッジが親子関係に違反している

エラー メッセージ

Foreign key constraint violation when deleting or updating referenced row(s): referencing row(s) found in table AccountTransferAccount

説明

AccountTransferAccount エッジ テーブルは ForeignKey を介して Account ノードテーブルを参照し、削除される Account ノードには引き続き入力方向のエッジが接続されています。

エラーの例

DELETE FROM Account WHERE id = 1;

まず、入力方向の Transfer エッジをすべて削除してから、Account ノードを削除します。または、ForeignKeyON DELETE CASCADE を定義し、Spanner でエッジを自動的に削除します。