1. مقدمة

غالبًا ما تتضمّن الأنشطة الاحتيالية شبكات مخفية من الجهات المرتبطة، مثل حسابات متعدّدة تشترك في عنوان البريد الإلكتروني أو رقم الهاتف أو العنوان الجغرافي نفسه. قد تواجه قواعد البيانات الارتباطية التقليدية صعوبة في الاستعلام عن هذه العلاقات المعقّدة والمتعددة المراحل بكفاءة.
تتيح لك خدمة BigQuery Graph تحليل هذه الشبكات على نطاق واسع باستخدام قواعد بيانات الرسومات البيانية. يمكنك تحديد رسم بياني للخصائص فوق جداول BigQuery الحالية واستخدام لغة طلبات البحث في الرسوم البيانية (GQL) للعثور على أنماط في بياناتك.
من التطبيقات الشائعة لشبكات الرسوم البيانية في رصد الاحتيال إيقاف الطلبات التي يتضمّن عنوان التسليم فيها شبكة مرتبطة بالاحتيال أو إيقاف الدفعات التي تنتمي إلى .
في هذا الدرس التطبيقي حول الترميز، ستنشئ حلاً لرصد الاحتيال باستخدام BigQuery Graph. ستحمّل البيانات من Cloud Storage، وتنشئ رسمًا بيانيًا للعلاقات، وتستخدم طلبات البحث في الرسم البياني لتحديد الروابط المشبوهة.
أهداف الدورة التعليمية
- كيفية إنشاء مجموعة بيانات في BigQuery وتحميل البيانات
- كيفية تحديد رسم بياني للخصائص باستخدام لغة تعريف البيانات (DDL)
- كيفية طلب البحث في الرسم البياني باستخدام GQL
- كيفية استخدام تحليلات الرسومات البيانية لرصد الاحتيال
المتطلبات
- مشروع Google Cloud تم تفعيل الفوترة فيه
- بيئة دفتر ملاحظات BigQuery (BigQuery Studio أو Colab Enterprise)
التكلفة
يستخدم هذا الدرس التطبيقي موارد Google Cloud قابلة للفوترة. التكلفة المقدّرة أقل من 5 دولارات أمريكية، على افتراض أنّك ستحذف الموارد بعد الانتهاء.
2. قبل البدء
اختيار مشروع على السحابة الإلكترونية أو إنشاؤه
- في Google Cloud Console، في صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئ مشروعًا.
- تأكَّد من تفعيل الفوترة لمشروعك على Google Cloud. كيفية التحقّق من تفعيل الفوترة
اختيار البيئة
ستحتاج إلى بيئة دفتر ملاحظات لتشغيل هذا الدرس التطبيقي. يمكنك استخدام BigQuery Studio أو Colab Enterprise.
- انتقِل إلى صفحة BigQuery في Google Cloud Console.
- ستستخدم دفتر Python لتنفيذ طلبات البحث في الرسم البياني.
بدء Cloud Shell
- انقر على تفعيل Cloud Shell في أعلى "وحدة تحكّم Google Cloud".
- إثبات صحة المصادقة:
gcloud auth list
- أكِّد مشروعك:
gcloud config get project
- اضبطه إذا لزم الأمر:
export PROJECT_ID=<YOUR_PROJECT_ID>
gcloud config set project $PROJECT_ID
تفعيل واجهات برمجة التطبيقات
نفِّذ الأمر التالي لتفعيل 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 لتضمين الجداول.
- في هذا الدرس التطبيقي، سننفّذ أوامر SQL. يمكنك تنفيذ هذه الأوامر في BigQuery Studio > محرِّر SQL، أو استخدام الأمر
bq queryفي Cloud Shell.
سنفترض أنّك تستخدم أداة تعديل SQL في BigQuery للحصول على تجربة أفضل مع عبارات الإنشاء المتعددة الأسطر.
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. إنشاء الرسم البياني للمواقع
بعد تحميل البيانات، يمكنك تحديد الرسم البياني للسمات. يتألف الرسم البياني للخصائص من عُقد (كيانات) وحواف (علاقات).
في هذا التمرين المعملي، تكون العُقد كما يلي:
- العميل: يمثّل صاحب الحساب.
- الهاتف: يمثّل رقم هاتف.
- البريد الإلكتروني: يمثّل عنوان بريد إلكتروني.
- العنوان: يمثّل عنوانًا جغرافيًا.
الحواف هي:
- OwnsPhone: لربط "العميل" بـ "الهاتف".
- OwnsEmail: لربط "عميل" بـ "بريد إلكتروني".
- LinkedToAddress: لربط "عميل" بـ "عنوان".

إنشاء الرسم البياني
نفِّذ عبارة DDL التالية لإنشاء الرسم البياني المسمّى FraudDemo في مجموعة البيانات fraud_demo.
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- تحليل الشبكات (خطوتان)
افتح دفتر ملاحظات جديد في BigQuery Studio.

بالنسبة إلى أجزاء التمثيل البصري والاقتراحات في هذا الدرس التطبيقي حول الترميز، سنستخدم دفتر ملاحظات Google Colab في BigQuery Studio. يتيح لنا ذلك عرض نتائج الرسم البياني بسهولة.
يتم تنفيذ BigQuery Graph Notebook كـ IPython Magics. من خلال إضافة الأمر السحري %%bigquery مع الدالة TO_JSON، يمكنك عرض النتائج كما هو موضّح في الأقسام التالية. في هذه الخطوة، ستنفّذ طلب بحث في الرسم البياني للعثور على روابط بسيطة بين الحسابات. هذا طلب بحث "بخطوتين" لأنّه ينتقل بخطوتين من عقدة البداية للعثور على العُقد ذات الصلة (مثل "العميل" -> "البريد الإلكتروني" -> "العميل").
سنبدأ بالتحقيق في الحساب الذي يخص نيكول ويد. نريد العثور على أي حسابات مرتبطة بها من خلال خطوتين.
تنفيذ طلب البحث المكوّن من خطوتَين
نفِّذ الطلب التالي في دفتر الملاحظات.
%%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

فهم النتائج
هذا الطلب:
- تبدأ في العقدة
Customerمعaccount_id"d2f1f992-d116-41b3-955b-6c76a3352657" (نيكول ويد). - تتبُّع أي من الحواف
OwnsEmailأوOwnsPhoneأوLinkedToAddressإلى عقدة ربط (PhoneأوEmailأوAddress) - تتتبّع الحواف من عقدة الربط هذه إلى عقد
Customerأخرى. - تتم فلترة الحواف استنادًا إلى طابع زمني (
last_updated_ts) للاطّلاع على حالة الشبكة في وقت محدّد.
يجب أن يظهر لك أنّ زكريا قرطبة وبرندا براون مرتبطان بـ "نيكول" من خلال العنوان نفسه.
6. تحليل الشبكات (4 قفزات)
في هذه الخطوة، ستوسّع نطاق طلب البحث للعثور على علاقات أكثر تعقيدًا. سنبحث عن عمليات ربط بأربع خطوات. يتيح لنا ذلك العثور على حسابات مرتبطة من خلال عدة كيانات وسيطة (مثل العميل أ -> البريد الإلكتروني -> العميل ب -> الهاتف -> العميل ج).
وسنراقب أيضًا كيف تتغير هذه الشبكة بمرور الوقت.
حالة "قبل"
أولاً، لنلقِ نظرة على الشبكة كما كانت في 30 يوليو 2025.
نفِّذ الاستعلام التالي:
%%bigquery --graph
%%bigquery --graph
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)]))
GRAPH fraud_demo.FraudDemo
RETURN
TO_JSON(p) AS paths, -- Array of all traversed edges
ARRAY_LENGTH(e) AS hop_count

حالة "بعد"
لنرى الآن كيف تبدو الشبكة بعد أسبوعَين. سننفّذ الاستعلام نفسه ولكن بدون القيود المتعلقة بالتاريخ.
نفِّذ الاستعلام التالي:
%%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

فهم النتائج
من خلال إزالة فلاتر التاريخ، يمكنك إجراء طلب بحث في مجموعة البيانات الكاملة. ستلاحظ أنّ الشبكة قد نمت بشكل كبير. أصبحت نيكول ويد الآن جزءًا من مجموعة أكبر بكثير ومرتبطة بشكل كبير. ويُعدّ هذا التوسّع السريع لشبكة مرتبطة مؤشرًا قويًا على النشاط الاحتيالي المحتمل، مثل مشاركة مجموعة احتيال للموارد بمرور الوقت.
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: معرّف الحساب الذي يتم تحليله. order_id: مُعرّف طلب حديثlatest_size: حجم الشبكة المتصلة اليومprevious_size: حجم الشبكة قبل أسبوعَينdiff: النمو في حجم الشبكة-
num_order: عدد الطلبات الأخيرة -
reported_as_fraud: ما إذا تم وضع علامة على الطلب باعتباره احتيالاً -
order_total: يشير إلى إجمالي مبلغ الطلب. notes: حالة المخاطرة المحسوبة استنادًا إلى نمو الشبكة وسجلّ الطلبات
ستظهر لك حسابات تتضمّن قيم diff كبيرة وإجمالي طلبات مرتفع، وهي مرشّحة أساسية لإجراء المزيد من التحقيقات. تساعد الملاحظتان "العميل المعرّض للخطر" و "طلب شراء محتمل أن يكون احتياليًا" في تحديد أولويات هذه الحسابات.

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- تنظيف
لتجنُّب تحمّل رسوم على حسابك على 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 للعثور على علاقات بسيطة ومعقّدة.
- يمكنك الجمع بين تحليلات الرسوم البيانية وبيانات النشاط الإعلاني لتحديد المخاطر.
- تصوُّر الشبكات على نطاق واسع
مزيد من المراجع