排查 Spanner 图问题

<ph type="x-smartling-placeholder">

本文档介绍了您可能会遇到的错误 。错误和建议的解决方法示例 。

架构错误

架构结果基于设置和查询中使用的数据集 Spanner 图

元素键必须具有唯一性保证

错误消息

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

N/A。不允许此条件。

属性定义在同一元素定义中必须保持一致

错误消息

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 图

图表元素无法作为查询结果返回

错误消息

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 图

不同的 WHEREFILTER 会导致不同的输出

说明

FILTER 是一个语句;WHERE 是一个子句,是 MATCH OPTIONAL MATCH 语句的一部分。

在第一个示例中,WHERE 子句为 OPTIONAL MATCH 语句中描述的模式。这不是过滤条件 匹配完成。

在第二个示例中,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 中,不存在 id 既是 7 又是 16Account 节点。如 返回空结果。

在示例 2 中,前一个语句未返回名称 n (仅返回 id)。因此,第二个 MATCH 会查找 Account 节点, id16

示例问题

以下示例具有不同的输出,因为不同的变量 会传播到多个语句。

示例 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 中,LIMIT 不会紧跟在 ORDER BY 后面;决赛 LIMIT 已分隔。这意味着引擎会忽略 ORDER BY

在示例 2 中,ORDER BY 适用,因为 LIMIT 紧跟在示例 2 中 ORDER BY

示例问题

以下示例具有不同的输出,因为 ORDER BY 在示例 1 中,当该语句在没有 LIMIT 的情况下使用时,该语句将被忽略。

示例 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 边匹配两次。

在示例 1 中,从 Account(id=x)Account(id=y)Transfers 边缘可以 两次,如下所示:

  • 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 中的查询返回 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 图

缺少源节点违反了外键限制条件

错误消息

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 表通过Accounttable ForeignKey 已调用 FK_TransferTo。为了创建 Transfer 边缘, 引用的尾节点“Account”节点必须已存在。

错误示例

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

先创建尾随账号节点,然后创建 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 节点。 或者,定义 ON DELETE CASCADE (为 INTERLEAVE),并让 Spanner 自动删除这些日志 边缘。

孤立的传入边缘违反了父子关系

错误消息

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

说明

AccountTransferAccount边缘表是指Account通过 ForeignKey,并且要删除的 Account 节点仍具有传入边缘 其他对象。

错误示例

DELETE FROM Account WHERE id = 1;

请先删除所有传入的 Transfer 边缘,然后再删除 Account 节点。 或者,定义 ON DELETE CASCADE (为 ForeignKey),并让 Spanner 自动删除这些日志 边缘。