运行 Spanner Graph 算法

本文档介绍了如何在 Spanner Graph 上运行算法。

Spanner Graph 算法查询结构

Spanner Graph 算法查询具有以下结构:

EXPORT DATA OPTIONS (export_option_list) AS
GRAPH graph_name
match_clause
call_statement algorithm_name(common_input, algorithm_specific_input)
  YIELD algorithm_specific_output
RETURN results
  • export_option_list:用于定义如何持久保存算法查询结果的选项。请参阅 Cloud Storage 选项和 Spanner 选项。

  • graph_name:图表的名称。

  • match_clause:用于定义算法输入元素的可选 MATCH 语句。

  • call_statement:如果您省略了 match_clause变量并希望对整个图表执行操作,请使用CALL语句。如果存在 match_clause 变量并且您希望对 工作表执行操作,请使用 CALL PER() 语句。 如需了解详情,请参阅 GQL CALL。

  • algorithm_name:要运行的算法的名称。如需了解 可用算法,请参阅 Spanner Graph 算法。

  • common_input:所有算法查询通用的命名输入参数。如需了解详情,请参阅 常用算法输入参数。

  • algorithm_specific_input:算法的命名输入参数。如需了解详情,请参阅 Spanner Graph 算法中定义的输入参数。

  • algorithm_specific_output:算法调用的输出。如需了解详情,请参阅 Spanner Graph 算法中定义的输出以及 YIELD子句在 CALL 语句中。

  • results:用于定义要在查询结果中返回的内容。

该查询由 EXPORT DATA 语句(用于定义如何 持久保存结果)和 生成算法查询结果的 GRAPH CLAUSE 子句组成。

最简单的形式是,graph 子句标识图表,使用 CALL 语句调用生成预定义输出的算法,然后使用 RETURN 语句指定要从算法的输出中返回的内容。

(可选)graph 子句可以使用受支持的 MATCH 语句来选择感兴趣的元素。在这种情况下,请使用 PER () 子句将 MATCH 语句返回的所有行分组为算法的输入。 该算法对由所选唯一节点和边组成的逻辑子图执行操作。

该查询不会返回任何数据。export_option_list 变量用于确定如何保留结果。

如需详细了解 Spanner Graph 算法查询,请参阅本文档中的以下部分:

常用算法输入参数

请按以下格式指定这些命名输入参数:NAME => VALUE, ...。

名称 值类型 必填 默认值 说明
node_labels ARRAY 否 (无) 仅在使用 CALL 时受支持。要包含在 算法输入中的节点标签列表。如果指定了此参数,则仅包含具有至少一个匹配 标签的节点。
edge_labels ARRAY 否 (无) 仅在使用 CALL 时受支持。要包含在 算法输入中的边标签列表。如果指定了此参数,则仅包含具有至少一个匹配 标签的边。
edge_weight_property STRING 否 (无) 包含权重的边属性的名称。 如果未定义,系统会为所有边分配默认权重 1。 属性值类型必须为数值。
machine_category STRING 否 默认 用于执行算法的机器类别。支持的值包括:default、large
fallback_compute_region STRING 否 (无) 如果主区域面临容量限制,则算法执行所在的备用区域。必须与 Spanner 实例的主区域位于同一司法管辖区(例如,如果主区域为 us-east1,则为 us-central1)。
max_idle_time STRING 否 30 分钟 指定在算法完成后,计算实例应保持活跃状态以供 重复使用的时间。格式为一系列十进制 数字,每个数字都带有一个单位后缀,例如 4m、1.5h 或 1h45m。有效时间单位为 ns、 us(或 µs)、ms、s、 m、h。

处理算法输出

您必须先持久保存算法查询结果,然后才能检查这些结果。使用 export_data_option 描述如何保留结果。您可以将结果持久保存到 Cloud Storage,也可以持久保存回查询来源的同一 Spanner 实例。

将结果持久保存到 Cloud Storage

如需使用此选项,请确保向 Google 管理的 Spanner 服务账号 service-PROJECT_NUMBER@gcp-sa-spanner.授予Storage Object Admin (roles/storage.objectAdmin) 角色。

将结果保留到 Cloud Storage 时,系统支持以下 EXPORT DATA 选项。请按以下格式指定选项:NAME=VALUE, ...。

名称 值类型 必填 说明
uri STRING 是 导出的目标 URI,格式为 gs://bucket/path/file。如果要导出大量数据,请在 uri 中使用通配符将数据导出到多个文件。例如,gs://bucket/path/file_*.csv。
format STRING 是 导出数据的格式。支持的值包括:CSV、PARQUET、AVRO。
header BOOL 否 如果为 true,系统会为每个数据文件的第一行打印列标题。默认值为 false。仅适用于 CSV。
overwrite BOOL 否 如果为 true,系统会覆盖具有相同 URI 的任何现有文件。否则,如果存在具有相同 URI 的文件,该语句会返回错误。默认值为 false。
field_delimiter STRING 否 用于分隔字段的定界符。默认值:,(英文逗号)。仅适用于 CSV。
compression STRING 否 指定压缩格式。如果您未指定压缩格式,文件将保持未压缩状态。
  • 对于 CSV,支持的值为 GZIP。
  • 对于 PARQUET,支持的值包括:SNAPPY、GZIP、ZSTD。
  • 对于 AVRO,支持的值包括:DEFLATE、SNAPPY。

RETURN 子句中的列名用于定义 Cloud Storage 输出文件中的列名。

将数据导出到一个或多个文件

Spanner Graph 查询支持在 uri 中使用单个通配符运算符 (*)。通配符可以出现在文件名组成部分中,但不能出现在存储桶名称、文件夹名称或文件扩展名中。如果结果集较大,使用通配符运算符可指示 Spanner Graph 根据您提供的模式创建多个分片文件。系统会将通配符运算符替换为数字(从零开始),并向左填充 12 位。例如,URI gs://my-bucket/file-*.csv 会创建类似 gs://my-bucket/file-000000000000.csv、gs://my-bucket/file-000000000001.csv 的文件。

如果您使用的 uri 不带通配符,则结果为单个文件,例如 gs://my-bucket/file.csv。

数据类型

导出数据时,Spanner Graph 数据类型会根据格式进行如下转换:

CSV

所有数据类型都会转换为其字符串表示形式:

  • BOOL 值会转换为 true 或 false。
  • BYTES 值会进行 Base64 编码。
  • TIMESTAMP 值会格式化为 YYYY-MM-DD HH:MM:SS.ffffff UTC。
  • NULL 值会显示为空字符串。

您不能使用 CSV 格式导出嵌套数据和重复数据。

Avro

Spanner 数据类型 Avro 数据类型
BOOL BOOLEAN
INT64 LONG
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC 逻辑类型为 DECIMAL(38,9) 的 BYTES
STRING STRING
BYTES BYTES
TIMESTAMP LONG(自 Epoch 以来的微秒数)
NULL null

Parquet

Spanner 数据类型 Parquet 数据类型
BOOL BOOLEAN
INT64 INT64
FLOAT FLOAT
DOUBLE DOUBLE
NUMERIC DECIMAL(38,9)
STRING STRING
BYTES BYTE_ARRAY
TIMESTAMP TIMESTAMP_MICROS
NULL null

将结果持久保存到 Spanner

将结果保留回源 Spanner 实例时,系统支持以下 EXPORT DATA 选项。请按以下格式指定选项:NAME=VALUE, ...。

名称 值类型 必填 说明
format STRING 是 导出数据的格式。必须为 CLOUD_SPANNER。
table STRING 是 要将结果写入的目标 Spanner 表的名称。 这可以是 Spanner 实例中的任何表。
write_mode STRING 是 要使用的写入模式。支持的值包括:
  • update_ignore_all:更新目标表中的现有行。
  • upsert_ignore_all:在目标表中插入新行或更新现有行。

在这两种模式下,Spanner 都会跳过任何会引入限制条件违规的记录(例如,更新时缺少键、唯一索引违规、外键限制条件违规)。不过,对于非限制条件违规错误(例如,列类型不匹配、NOT NULL 列缺少值),写入会失败。

要求

将算法结果持久保存回 Spanner 时,算法查询必须满足以下条件:

  • 目标表必须存在 。
  • 必须存在具有匹配类型的列: RETURN子句中指定的所有列名都必须已存在于目标表中,并且具有匹配的 数据类型。如果需要,请使用别名来匹配目标表列名。示例:RETURN node.id AS person_id。
  • 包含所有主键列:RETURN子句必须包含目标表的所有 主键列。

写入语义

将结果保留回 Spanner 是一种非事务性操作。它提供行级原子性。这意味着,系统要么成功写入同一行的所有列,要么不写入任何列。它遵循“至少一次”语义。这意味着一行可以写入多次。在执行过程中从目标表中读取数据可能会产生不完整的结果。

如果整体执行失败,系统不会回滚已提交的更改。写入过程会在第一个不可重试的错误上失败。发生写入失败时,ERROR_MESSAGE 在 GRAPH_OPERATION_EXECUTION_STATUS 中会指示失败行的主键以及失败的具体 原因。

系统使用 MEDIUM 优先级将算法结果写回 Spanner Graph。

运行示例算法查询

本部分展示了您可以在测试实例上运行的 Spanner Graph 算法查询示例。如需查看 Spanner Graph 支持的算法的完整列表,请参阅 Spanner Graph 算法。

准备工作

如需运行示例 Spanner Graph 算法查询,您必须先完成以下操作:

  1. 按照设置和查询 Spanner Graph 中的步骤创建 Spanner Graph。
  2. 确保您拥有所需的权限。
  3. (可选)如果您要将输出保留到 Spanner,请扩充 Spanner Graph 架构。

向 Account 表添加名为 page_rank 的新列。Spanner 会将算法结果写入此新列。然后,刷新图表定义,以便您可以将 page_rank 作为节点属性进行访问。

-- Add `page_rank` as a column. Data type of this column matches the data type defined in `PageRank` output signature.
ALTER TABLE Account ADD COLUMN page_rank FLOAT64;

-- Rerun the graph definition DDL to pickup `page_rank` as a new property.
CREATE OR REPLACE PROPERTY GRAPH FinGraph
  NODE TABLES (`Account`, `Person`)
  EDGE TABLES (
    `PersonOwnAccount`
      SOURCE KEY (id) REFERENCES `Person` (id)
      DESTINATION KEY (account_id) REFERENCES `Account` (id)
      LABEL `Owns`,
    `AccountTransferAccount`
      SOURCE KEY (id) REFERENCES `Account` (id)
      DESTINATION KEY (to_id) REFERENCES `Account` (id)
      LABEL `Transfers`
  );

对带有标签过滤器的完整图表运行算法,并将结果保留到 Cloud Storage

此示例运行 PageRank 语句,以根据账号参与的转移对账号进行排名。查询结果以 CSV 格式保留到 Cloud Storage 存储桶中,格式为 my-bucket-name/my-output.csv。

EXPORT DATA OPTIONS (
  uri = "gs://my-bucket-name/my-output.csv",
  format = "csv"
) AS
GRAPH FinGraph
CALL PageRank(node_labels => ['Account'], edge_labels => ['Transfers']) YIELD node, score
RETURN node.id, score AS page_rank

在 Cloud Storage 中,当此查询成功完成时,您应该会看到一个包含两列(id 和 page_rank)的 CSV 文件。

对由 MATCH 定义的子图运行算法,并将结果保留到图表中

此示例使用 MATCH 模式动态匹配包含所有 Account 节点且金额小于 500 的 Transfer 边的逻辑子图。 此逻辑子图是 PageRank 算法的输入。 Spanner 会将算法结果保留回 Account 表。

EXPORT DATA OPTIONS (
  format = "CLOUD_SPANNER",
  table = "Account",
  write_mode = 'update_ignore_all'
) AS
GRAPH FinGraph
MATCH (n:Account)
RETURN n
FULL UNION ALL
MATCH -[e:Transfers WHERE e.amount < 500]->
RETURN e
NEXT
CALL PER () PageRank() YIELD node, score
RETURN node.id, score AS page_rank

查询成功完成后,运行以下查询:

GRAPH FinGraph
MATCH (n:Account)
RETURN n.id, ROUND(n.page_rank, 2) AS page_rank
ORDER BY page_rank DESC, id ASC

您应该会看到如下所示的结果:

id page_rank
20 0.49
16 0.46
7 0.05

检查算法执行状态

图算法查询成功完成后,会返回零行和 Success 状态。根据输入图表的大小和特定算法配置,算法执行可能需要一段时间才能完成。您可以在 SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS 表中检查图算法查询的进度和执行状态。此表会保留 30 天的信息。

GRAPH_OPERATION_EXECUTION_STATUS 架构

列名 类型 说明
QUERY_ID STRING 图算法查询的 ID。
QUERY_TEXT STRING 查询语句文本。
START_TIMESTAMP TIMESTAMP 查询开始执行的时间。
LAST_UPDATE_TIMESTAMP TIMESTAMP 状态上次更新的时间。
PROGRESS FLOAT64 估计完成百分比。该值介于 0 和 1 之间,其中 0 表示已开始,1 表示已完成。
STATUS STRING 当前的执行状态。可能的值包括 PENDING、IN_PROGRESS、OK 或错误状态代码,例如 CANCELLED、DEADLINE_EXCEEDED、INVALID_ARGUMENT、FAILED_PRECONDITION、RESOURCE_EXHAUSTED、UNAVAILABLE 或 UNKNOWN。
ERROR_MESSAGE STRING 如果查询执行失败,则返回出错提示。

以下示例查询列出了尚未成功完成的图表查询:

SELECT
  query_id,
  query_text,
  start_timestamp,
  last_update_timestamp,
  progress,
  status,
  error_message
FROM
  SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS
WHERE
  status != "OK"
ORDER BY
  start_timestamp DESC;

取消算法执行

如需取消正在进行的图算法查询,请从 SPANNER_SYS.GRAPH_OPERATION_EXECUTION_STATUS表中找到query_id,然后针对该query_id调用 cancel_query 。

后续步骤