1. 简介

欺诈活动通常涉及隐藏的关联实体网络,例如多个账号共享同一电子邮件地址、电话号码或实际地址。传统的关联数据库可能难以高效查询这些复杂的多跳关系。
借助 BigQuery Graph ,您可以使用图数据库大规模分析这些网络。您可以在现有 BigQuery 表的基础上定义属性图,并使用 Graph Query Language (GQL) 查找数据中的模式。
图网络在欺诈检测方面的一个常见应用是阻止与欺诈网络关联的配送地址的订单,或阻止属于欺诈网络的付款。
在此 Codelab 中,您将使用 BigQuery Graph 构建欺诈检测解决方案。您将从 Cloud Storage 加载数据,创建属性图,并使用图查询来识别可疑的连接。
学习内容
- 如何在 BigQuery 中创建数据集并加载数据。
- 如何使用 DDL 定义属性图。
- 如何使用 GQL 查询图。
- 如何使用图分析来检测欺诈。
所需条件
- 启用了结算功能的 Google Cloud 项目。
- BigQuery 笔记本环境(BigQuery Studio 或 Colab Enterprise)。
费用
此实验使用可计费的 Google Cloud 资源。假设您在完成实验后删除资源,则预计费用低于 5 美元。
2. 准备工作
选择或创建 Google Cloud 项目
- 在 Google Cloud 控制台的“项目选择器”页面上,选择或创建一个 Google 云项目。
- 确保您的 Google Cloud 项目已启用结算功能。了解如何检查是否已启用结算功能。
选择您的环境
您需要一个笔记本环境来运行此实验。您可以使用 BigQuery Studio 或 Colab Enterprise 。
- 在 Google Cloud 控制台中前往 BigQuery 页面。
- 您将使用 Python 笔记本运行图查询。
启动 Cloud Shell
- 点击 Google Cloud 控制台顶部的激活 Cloud Shell 。
- 核实身份验证:
gcloud auth list
- 确认您的项目:
gcloud config get project
- 如有必要,请进行设置:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
启用 API
运行此命令以启用所需的 BigQuery API:
gcloud services enable bigquery.googleapis.com
3. 加载数据
在此步骤中,您将创建一个 BigQuery 数据集,并从 Cloud Storage 加载示例数据。
示例数据包含多个 CSV 文件,这些文件代表模拟的零售环境:
customers.csv:客户账号信息。emails.csv:电子邮件地址。phones.csv:电话号码。addresses.csv:实际地址。customer_emails.csv、customer_phones.csv、customer_addresses.csv:链接表。orders.csv:订单记录,包括欺诈标志。
创建数据集
创建一个名为 fraud_demo 的数据集来存储表。
- 在此 Codelab 中,我们将执行 SQL 命令。您可以在 BigQuery Studio > SQL 编辑器 中运行这些命令,也可以在 Cloud Shell 中使用
bq query命令。
我们将假定您使用的是 BigQuery SQL 编辑器 ,以便更好地使用多行创建语句。
CREATE SCHEMA IF NOT EXISTS `fraud_demo` OPTIONS(location="US");
加载表
运行以下 SQL 语句,将数据从 Cloud Storage 加载到您的数据集中。
LOAD DATA OVERWRITE `fraud_demo.customers`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customers.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.emails`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/emails.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.phones`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/phones.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.addresses`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/addresses.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_emails`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_emails.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_phones`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_phones.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.customer_addresses`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/customer_addresses.csv'],
skip_leading_rows = 1
);
LOAD DATA OVERWRITE `fraud_demo.orders`
FROM FILES (
format = 'CSV',
uris = ['gs://sample-data-and-media/fraud-demo-data/orders.csv'],
skip_leading_rows = 1
);
4. 创建属性图
现在数据已加载完毕,您可以定义属性图了。属性图由节点(实体)和边(关系)组成。
在此实验中,节点包括:
- Customer:表示账号持有人。
- 电话:表示电话号码。
- Email:表示电子邮件地址。
- Address:表示实际地址。
边包括:
- OwnsPhone:将客户连接到电话号码。
- OwnsEmail:将客户连接到电子邮件地址。
- LinkedToAddress:将客户连接到地址。

创建图
运行以下 DDL 语句,在 fraud_demo 数据集中创建名为 FraudDemo 的图。
CREATE OR REPLACE PROPERTY GRAPH fraud_demo.FraudDemo
NODE TABLES(
fraud_demo.customers
KEY(account_id)
LABEL Customer PROPERTIES(
account_id,
name),
fraud_demo.emails
KEY(email)
LABEL Email PROPERTIES(
email,
email_type),
fraud_demo.phones
KEY(phone_number)
LABEL Phone PROPERTIES(
phone_number,
phone_type),
fraud_demo.addresses
KEY(address)
LABEL Address PROPERTIES(
address,
address_type)
)
EDGE TABLES(
fraud_demo.customer_emails
KEY(account_id, email)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(email) REFERENCES emails(email)
LABEL OwnsEmail PROPERTIES(
account_id,
email,
last_updated_ts),
fraud_demo.customer_phones
KEY(account_id, phone_number)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(phone_number) REFERENCES phones(phone_number)
LABEL OwnsPhone PROPERTIES(
account_id,
phone_number,
last_updated_ts),
fraud_demo.customer_addresses
KEY(account_id, address)
SOURCE KEY(account_id) REFERENCES customers(account_id)
DESTINATION KEY(address) REFERENCES addresses(address)
LABEL LinkedToAddress PROPERTIES(
account_id,
address,
last_updated_ts)
);
5. 分析网络(2 跳)
在 BigQuery Studio 中打开新建笔记本 。

对于此 Codelab 的可视化和建议部分,我们将使用 BigQuery Studio 中的 Google Colab 笔记本。这样,我们就可以轻松直观呈现图结果。
将以下内容粘贴到代码单元中:
!pip install bigquery-magics==0.12.1
BigQuery Graph 笔记本以 IPython 魔法命令的形式实现。通过添加带有 TO_JSON 函数的 %%bigquery 魔法命令,您可以直观呈现结果,如以下部分所示。在此步骤中,您将运行图查询来查找账号之间的简单连接。这是一个“2 跳”查询,因为它从起始节点跳出 2 跳来查找相关节点(例如,客户 -> 电子邮件 -> 客户)。
我们将首先调查属于 Nicole Wade 的账号。我们希望找到通过 2 跳与她相关的任何账号。
运行 2 跳查询
在笔记本中运行以下查询。
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH
p=(a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']- (n) ){2}
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Verify the final node in the hop array is a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(1)]))
RETURN TO_JSON(p) AS paths

解读结果
此查询执行以下操作:
- 从
account_id为“d2f1f992-d116-41b3-955b-6c76a3352657”(Nicole Wade)的Customer节点开始。 - 沿着
OwnsEmail、OwnsPhone或LinkedToAddress中的任何一条边到达连接节点(Phone、Email或Address)。 - 从该连接节点沿着边返回到其他
Customer节点。 - 根据时间戳 (
last_updated_ts) 过滤边,以查看特定时间点的网络状态。
您应该会看到 Zachary Cordova 和 Brenda Brown 通过同一地址与 Nicole 连接。
6. 分析网络(4 跳)
在此步骤中,您将扩展查询以查找更复杂的关系。我们将查找 4 跳 连接。这样,我们就可以找到通过多个中间实体连接的账号(例如,客户 A -> 电子邮件 -> 客户 B -> 电话 -> 客户 C)。
我们还将观察此网络随时间的变化情况。
“之前”状态
首先,我们来看看 2025 年 7 月 30 日 的网络。
运行以下查询:
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']- (n) ){3, 5}(reachable_a:Customer)
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Ensure the final node in the dynamic chain is actually a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(ARRAY_LENGTH(n) - 1)]))
RETURN
TO_JSON(p) AS paths, -- Array of all traversed edges
ARRAY_LENGTH(e) AS hop_count

“之后”状态
现在,我们来看看 2 周后 的网络。我们将运行相同的查询,但没有日期限制。
运行以下查询:
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress]- (n) ){3, 5}(reachable_a:Customer)
WHERE a.account_id IN ("d2f1f992-d116-41b3-955b-6c76a3352657")
-- Ensure the final node in the dynamic chain is actually a Customer
AND 'Customer' IN UNNEST(LABELS(n[OFFSET(ARRAY_LENGTH(n) - 1)]))
RETURN
TO_JSON(p) AS paths, -- Array of all traversed edges
ARRAY_LENGTH(e) AS hop_count

解读结果
移除日期过滤条件后,您将针对完整数据集进行查询。您会注意到,网络规模显著扩大。Nicole Wade 现在属于一个规模大得多且高度互联的群组。互联网络的这种快速扩张是潜在欺诈活动的有力指标,例如欺诈团伙随着时间的推移共享资源。
7. 生成欺诈报告
在此步骤中,您将图分析与传统商家数据(订单)相结合,生成全面的欺诈报告。您将识别有风险的账号和潜在的欺诈订单。
此查询较为复杂。它使用 GRAPH_TABLE 在标准 SQL 中运行图查询,并计算我们在上一步中观察到的“之前”和“之后”状态之间的网络规模变化 (diff)。
运行欺诈报告查询
在笔记本中运行以下查询。
%%bigquery --graph
WITH num_orders AS (
SELECT account_id, COUNT(1) AS num_order
FROM fraud_demo.orders
WHERE order_time > '2025-07-30'
GROUP BY account_id
),
orders AS (
SELECT account_id, order_id, fraud, order_total
FROM fraud_demo.orders
WHERE order_time > '2025-07-30'
),
-- Use Quantified Path Patterns to find connections up to 4 hops away
latest_connect AS (
SELECT
account_id,
ARRAY_LENGTH(ARRAY_AGG(DISTINCT connected_id)) AS size
FROM GRAPH_TABLE(
fraud_demo.FraudDemo
MATCH (a:Customer)-[:OwnsEmail|OwnsPhone|LinkedToAddress]-{4}(connected:Customer)
RETURN a.account_id AS account_id, connected.account_id AS connected_id
)
GROUP BY account_id
),
prev_connect AS (
SELECT
account_id,
ARRAY_LENGTH(ARRAY_AGG(DISTINCT connected_id)) AS size
FROM GRAPH_TABLE(
fraud_demo.FraudDemo
-- Apply the timestamp filter to EVERY edge in the 4-hop chain
MATCH (a:Customer)
(-[e:OwnsEmail|OwnsPhone|LinkedToAddress WHERE e.last_updated_ts < '2025-07-30']-(n)){4}
WHERE 'Customer' IN UNNEST(LABELS(n[OFFSET(3)]))
RETURN a.account_id AS account_id, n[OFFSET(3)].account_id AS connected_id
)
GROUP BY account_id
),
edge_changes AS (
SELECT account_id, MAX(last_updated_ts) AS max_last_updated_ts
FROM fraud_demo.customer_addresses
GROUP BY account_id
)
SELECT
la.account_id,
o.order_id,
la.size AS latest_size,
COALESCE(pa.size, 0) AS previous_size,
la.size - COALESCE(pa.size, 0) AS diff,
nos.num_order,
o.fraud AS reported_as_fraud,
o.order_total,
CASE
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NULL THEN "CUSTOMER AT RISK"
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NOT NULL AND o.fraud THEN "CONFIRMED FRAUD ORDER"
WHEN (la.size - COALESCE(pa.size, 0)) > 10 AND nos.num_order IS NOT NULL AND NOT o.fraud THEN "POTENTIAL FRAUD ORDER"
ELSE ""
END AS notes
FROM latest_connect la
LEFT JOIN prev_connect pa ON la.account_id = pa.account_id
LEFT JOIN num_orders nos ON la.account_id = nos.account_id
LEFT JOIN orders o ON la.account_id = o.account_id
INNER JOIN edge_changes ec ON la.account_id = ec.account_id
WHERE nos.num_order > 1 OR (la.size - COALESCE(pa.size, 0)) > 10
ORDER BY diff DESC
解读结果
此报告显示:
account_id:要分析的账号的 ID。order_id:最近的订单 ID。latest_size:今天互联网络的规模。previous_size:2 周前的网络规模。diff:网络规模的增长。num_order:最近的订单数。reported_as_fraud:订单是否已标记为欺诈。order_total:订单总金额。notes:根据网络增长和订单记录计算出的风险状态。
您将看到 diff 值较大且订单总金额较高的账号,这些账号是进一步调查的主要候选对象。“CUSTOMER AT RISK”和“POTENTIAL FRAUD ORDER”备注有助于确定这些账号的优先级。

8. 大规模检测
在此最终分析步骤中,您将以更大的规模直观呈现网络。您将查询一组可疑账号之间的连接,而不是从单个账号开始。
这有助于您了解多项独立调查是否实际上属于同一更大的欺诈团伙。
运行大规模查询
在笔记本中运行以下查询。
%%bigquery --graph
GRAPH fraud_demo.FraudDemo
MATCH
p= ANY SHORTEST (a:Customer)
( -[e:OwnsEmail|OwnsPhone|LinkedToAddress]- (n) ){3, 5}
(reachable_a:Customer)
-- these IDs are from the previous results
WHERE a.account_id in ( "845f2b14-cd10-4750-9f28-fe542c4a731b"
, "3ff59684-fbf9-40d7-8c41-285ade5002e6"
, "8887c17b-e6fb-4b3b-8c62-cb721aafd028"
, "03e777e5-6fb4-445d-b48c-cf42b7620874"
, "81629832-eb1d-4a0e-86da-81a198604898"
, "845f2b14-cd10-4750-9f28-fe542c4a731b",
"89e9a8fe-ffc4-44eb-8693-a711a3534849"
)
LIMIT 400
RETURN TO_JSON(p) as paths
解读结果
此查询会返回一个复杂的图,显示指定的可疑账号如何重叠和共享资源。您现在正在大规模进行欺诈检测,识别可能需要协调响应的活动集群。

9. 清理
为避免系统因本 Codelab 中使用的资源向您的 Google Cloud 账号收取费用,您应该删除数据集和属性图。
运行以下 SQL 语句以清理您的环境。
DROP PROPERTY GRAPH IF EXISTS fraud_demo.FraudDemo;
DROP SCHEMA IF EXISTS fraud_demo CASCADE;
10. 恭喜
恭喜!您已成功使用 BigQuery Graph 构建了欺诈检测解决方案。
您已了解如何:
- 将数据从 Cloud Storage 加载到 BigQuery。
- 使用 DDL 定义属性图。
- 使用 GQL 查询图,以查找简单和复杂的关系。
- 将图分析与商家数据相结合,以识别风险。
- 大规模直观呈现网络。