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 は、MATCHOPTIONAL 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 では、id716 の両方である 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 では、LIMITORDER BY の直後に続くため、ORDER BY が適用されます。

問題の例

以下の例では出力が異なります。これは例 1 で LIMIT なしで使用される場合に ORDER BY ステートメントが無視されるためです。

例 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 でエッジを自動的に削除します。