تتبُّع مصدر المنتجات في سلسلة التوريد باستخدام BigQuery Graph

1- مقدمة

في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية الاستفادة من BigQuery Graph لحلّ المشاكل المعقّدة في سلسلة الإمداد والخدمات اللوجستية.

ستنشئ نموذجًا لشبكة سلسلة إمداد مطعم مع التركيز على سلامة الأغذية ومراقبة الجودة. عند حدوث مشكلة في سلامة الأغذية، مثل تلوّث أحد المكوّنات من أحد المورّدين، يصبح الوقت عاملاً حاسمًا. يمكن أن يؤدي تحديد "نطاق التأثير" وتنفيذ عملية سحب دقيقة بسرعة إلى توفير التكاليف وحماية العملاء.

الخوف من تناول الطعام في المطاعم

تتطلّب النماذج العلائقية التقليدية عمليات JOIN معقّدة ومتعدّدة الخطوات لتتبُّع السلع خلال مراحل متعدّدة (المورّد -> مركز التوزيع -> المطبخ -> المتجر -> السلعة النهائية). باستخدام BigQuery Graph، ننشئ نموذجًا لهذه الاتصالات مباشرةً، ما يتيح إجراء طلبات بحث سريعة وبشكل بديهي باستخدام معيار ISO GQL (لغة طلبات البحث في الرسم البياني).

أهداف الدورة التعليمية

  • كيفية تحديد نموذج رسم بياني فوق جداول BigQuery الحالية
  • كيفية إنشاء رسم بياني للخصائص داخل BigQuery
  • كيفية تشغيل طلبات بحث عن الاجتياز لتتبُّع التأثيرات في المراحل السابقة واللاحقة

المتطلبات

  • مشروع على Google Cloud تم تفعيل الفوترة فيه
  • Google Cloud Shell

تقدير التكلفة

من المتوقّع أن تكلّف هذه التجربة أقل من 5 دولارات أمريكية في رسوم تحليل BigQuery، وهو مبلغ أقل بكثير من مخصّصات المستوى المجاني للمستخدمين الجدد.

2. الإعداد والمتطلبات

فتح Cloud Shell

ستنفّذ معظم العمل في Cloud Shell، وهي بيئة محملة تتضمّن كل ما تحتاج إليه لاستخدام Google Cloud.

  1. انتقِل إلى Google Cloud Console.
  2. انقر على رمز تفعيل Cloud Shell في شريط الأدوات أعلى يسار الصفحة.
  3. انقر على متابعة إذا طُلب منك ذلك.

إعداد المتغيّرات البيئية

في Cloud Shell، اضبط رقم تعريف مشروعك لتسهيل الأوامر المستقبلية.

export PROJECT_ID=$(gcloud config get-value project)

تفعيل BigQuery API

تأكَّد من تفعيل BigQuery API. عادةً ما تكون هذه الخدمة مفعّلة تلقائيًا، ولكن من الأفضل التأكّد من ذلك.

gcloud services enable bigquery.googleapis.com

3. إنشاء المخطط والجداول

ستنشئ مجموعة بيانات وجداول تمثّل مكوّنات سلسلة الإمداد:

  • item: تعريف السلعة العامة (مثل طماطم أو دجاج)
  • location: المرافق (المورّدون ومراكز التوزيع والمقاهي)
  • itemlocation: جدول التقاطع الذي يمثّل مواقع المستودع
  • bom: قائمة المواد (تحدّد علاقات الوزن، مثلاً، يتم استخدام السلعة "أ" في السلعة "ب")
  • makes: يربط itemlocation بـ item
  • stored_at: يربط itemlocation بـ location

إنشاء مجموعة بيانات

يمكنك تشغيل أوامر SQL في هذا الدرس التطبيقي باستخدام Cloud Shell أو BigQuery Console.

لاستخدام BigQuery Console:

  1. افتح BigQuery Console في علامة تبويب جديدة.
  2. الصِق كل مقتطف من SQL من هذا الدرس التطبيقي في المحرّر، ثم انقر على الزر تشغيل لتنفيذه.

محرّر BigQuery

شغِّل الأمر التالي في Cloud Shell أو استخدِم BigQuery Console لإنشاء المخطط. ستستخدِم متغيّرات العُقد في SQL.

مخطط بيانات BigQuery

ملاحظة: (1) لتنفيذ هذا الإجراء في Google Colab، يمكنك أيضًا استخدام أوامر BigQuery السحرية: ‎%%bigquery ينشئ المقتطف التالي مخطط المطعم ضمن مشروعك لتخزين بيانات الرسم البياني. (2) عليك استخدام ‎ %%bigquery –project <PROJECT_ID> إذا كنت تُشغِّل من Google Colab. تأكَّد من ربط الحقل PROJECT_ID بالمشروع المناسب الذي تنوي استخدامه: PROJECT_ID = "argolis-project-340214" # @param {"type":"string"} (3) إذا كنت تستخدِم Colab، عليك تثبيت بعض المكتبات حسب متطلباتك. إذا كنت ستستخدِم عرض الرسم البياني، تأكَّد من تنفيذ الأمر pip install للمكتبة: spanner-graph-notebook==1.1.5

BigQuery Magic في Colab

%%bigquery --project=$PROJECT_ID
CREATE SCHEMA IF NOT EXISTS restaurant ;

إنشاء الجداول

نفِّذ رمز SQL التالي لإنشاء الجداول.

%%bigquery --project=$PROJECT_ID
-- 1. Item Table
DROP TABLE IF EXISTS `restaurant.item`;
CREATE TABLE `restaurant.item` (
  itemKey STRING,
  itemName STRING,
  itemCategory STRING,
  shelfLifeDays INT64,
  PRIMARY KEY (itemKey) NOT ENFORCED
);

-- 2. Location Table
DROP TABLE IF EXISTS `restaurant.location`;
CREATE TABLE `restaurant.location` (
  locationKey STRING,
  locationType STRING,
  locationCity STRING,
  locationState STRING,
  dunsNumber INT64,
  PRIMARY KEY (locationKey) NOT ENFORCED
);
-- 3. ItemLocation Table
DROP TABLE IF EXISTS `restaurant.itemlocation`;
CREATE TABLE `restaurant.itemlocation` (
  itemLocationKey STRING,
  itemKey STRING,
  locationKey STRING,
  variants INT64,
  PRIMARY KEY (itemLocationKey) NOT ENFORCED,
  -- Foreign Key Definitions
  FOREIGN KEY (itemKey) REFERENCES `restaurant.item`(itemKey) NOT ENFORCED,
  FOREIGN KEY (locationKey) REFERENCES `restaurant.location`(locationKey) NOT ENFORCED
);

-- 4. BOM Table
DROP TABLE IF EXISTS `restaurant.bom`;
CREATE TABLE `restaurant.bom` (
  bomKey INT64,
  parentItemLocation STRING,
  childItemLocation STRING,
  childQuantity FLOAT64,
  PRIMARY KEY (bomKey) NOT ENFORCED
);

-- 5. Makes Table
DROP TABLE IF EXISTS `restaurant.makes`;
CREATE TABLE `restaurant.makes` (
  itemLocationKey STRING,
  itemKey STRING,
  locationKey STRING,
  variants INT64,
  PRIMARY KEY (itemLocationKey) NOT ENFORCED
);

DROP TABLE IF EXISTS `restaurant.stored_at`;
CREATE TABLE `restaurant.stored_at` (
  itemLocationKey STRING,
  itemKey STRING,
  locationKey STRING,
  variants INT64,
  PRIMARY KEY (itemLocationKey) NOT ENFORCED
);

4. تحميل بيانات نموذجية

لجعل هذا الدرس التطبيقي مكتفياً ذاتيًا بالكامل، ستملأ الجداول ببيانات نموذجية باستخدام عبارات LOAD DATA بلغة SQL فقط. يمثّل ذلك شبكة تبدأ بـ مورّد، وتنتقل عبر مركز توزيع ومطبخ، وتصل إلى مقهى للبيع بالتجزئة.

شغِّل طلبات بحث SQL التالية لتحميل البيانات:

تحميل البيانات في BigQuery

ملاحظة: يمكنك حذف ‎ %%bigquery إذا كنت تُشغِّل مباشرةً في BigQuery Studio

%%bigquery --project=$PROJECT_ID
-- Load Item
LOAD DATA OVERWRITE `restaurant.item`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/item2.csv'], skip_leading_rows = 1);

-- Load Location
LOAD DATA OVERWRITE `restaurant.location`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/location.csv'], skip_leading_rows = 1);

-- Load ItemLocation
LOAD DATA OVERWRITE `restaurant.itemlocation`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/itemlocation.csv'], skip_leading_rows = 1);

-- Load BOM
LOAD DATA OVERWRITE `restaurant.bom`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/bom2.csv'], skip_leading_rows = 1);

-- Load Makes
LOAD DATA OVERWRITE `restaurant.makes`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/makes.csv'], skip_leading_rows = 1);

-- Load StoredAt
LOAD DATA OVERWRITE `restaurant.stored_at`
FROM FILES (format = 'CSV', uris = ['gs://supply_chain_demo/itemlocation.csv'], skip_leading_rows = 1);

5. إضافة القيود وتحديد الرسم البياني

قبل إنشاء الرسم البياني، عليك الإعلان عن العلاقات الدلالية باستخدام قيود المفتاح الأساسي والمفتاح الخارجي في SQL العادية. تساعد هذه القيود BigQuery في فهم معرّفات العُقد وربط جداول الحواف بجداول العُقد.

إنشاء رسم بياني للخصائص

الآن، يمكنك دمج هذه الجداول في بنية رسم بياني متماسكة واحدة باسم restaurant.bombod.

يمكنك تحديد:

  • العُقد: item، location، itemlocation
  • الحواف: makes، stored_at، وconsists_of (قائمة المواد)
%%bigquery --project=$PROJECT_ID

CREATE OR REPLACE PROPERTY GRAPH `restaurant.bombod`
NODE TABLES (
  `restaurant.item` KEY (itemKey) LABEL item PROPERTIES ALL COLUMNS,
  `restaurant.location` KEY (locationKey) LABEL location PROPERTIES ALL COLUMNS,
  `restaurant.itemlocation` KEY (itemLocationKey) LABEL itemlocation PROPERTIES ALL COLUMNS
)
EDGE TABLES (
  `restaurant.makes`
    KEY (itemLocationKey)
    SOURCE KEY (itemLocationKey) REFERENCES `restaurant.itemlocation`(itemLocationKey)
    DESTINATION KEY (itemKey) REFERENCES `restaurant.item`(itemKey)
    LABEL makes PROPERTIES ALL COLUMNS,

  `restaurant.bom`
    KEY (bomKey)
    SOURCE KEY (childItemLocation) REFERENCES `restaurant.itemlocation`(itemLocationKey)
    DESTINATION KEY (parentItemLocation) REFERENCES `restaurant.itemlocation`(itemLocationKey)
    LABEL consists_of PROPERTIES ALL COLUMNS,

  `restaurant.stored_at`
    KEY (itemLocationKey)
    SOURCE KEY (itemLocationKey) REFERENCES `restaurant.itemlocation`(itemLocationKey)
    DESTINATION KEY (locationKey) REFERENCES `restaurant.location`(locationKey)
    LABEL stored_at PROPERTIES ALL COLUMNS
);

6. عرض سلسلة الإمداد

يمكنك تشغيل طلب بحث عن الاجتياز من أعلى إلى أسفل للاطّلاع على شبكة سلسلة الإمداد بأكملها. في دفتر ملاحظات عادي أو واجهة مستخدم تتيح ذلك (مثل %%bigquery --graph)، يعرض هذا الطلب خريطة مرئية.

استخدِم طلبات بحث الرسم البياني المطلقة لإعداد العُقد والحواف.

ملاحظة: كما ذكرنا سابقًا، لتنفيذ هذا الإجراء في Google Colab أو Colab Enterprise Notebooks، يمكنك أيضًا استخدام أوامر BigQuery السحرية: ‎%%bigquery ولعرض الرسم البياني في Google Colab أو Colab Enterprise Notebooks، عليك تضمين العلامة ‎–graph على النحو التالي: ‎%%bigquery –graph

%%bigquery  --project=$PROJECT_ID --graph output

Graph restaurant.bombod

match p=(a:itemlocation)-[c:consists_of]->(b:itemlocation)
match q=(a)-[d:stored_at]->(e:location)
optional match z=(f)-[g:makes]-(b)

return to_json(p) as ppath, to_json(q) as qpath, to_json(z) as zpath

إخراج:

الرسم البياني لتجهيزات المطاعم

7. حالة الاستخدام 1: تتبُّع شكوى من المراحل السابقة

السيناريو: يشتكي أحد العملاء من جودة الدجاج في الساندويتش الذي اشتراه من متجر نيويورك. عليك تتبُّع السلعة النهائية للخلف للاطّلاع على مراحل تجميعها المباشرة.

طلب بحث عن المسح

شغِّل طلب البحث باستخدام تنسيق طلب البحث عن اجتياز الرسم البياني. يبحث هذا الطلب عن حواف consists_of التي تربط عمليات التجميع في المراحل اللاحقة بالمكوّنات في المراحل السابقة.

%%bigquery --project=$PROJECT_ID --graph

GRAPH restaurant.bombod
MATCH p=(a:itemlocation)-[c:consists_of]->(b:itemlocation)
OPTIONAL MATCH q=(b)-[d:stored_at]-(e)
return to_json(p) as ppath, to_json(q) as qpath

بسبب اتجاه السهم في جدول الحواف consists_of (Ingredient -> Finished)، يؤدي البحث الذي ينتقل من المراحل اللاحقة إلى المراحل السابقة إلى عرض روابط تعزل بسرعة المواد ومواقع التخزين التابعة.

الإخراج: الاطّلاع على مصدر الدجاج

8. حالة الاستخدام 2: تحليل التأثير

السيناريو: أدت عاصفة ثلجية إلى إغلاق مركز التوزيع في كولومبوس، أوهايو. عليك معرفة التحضيرات أو السلع النهائية في المراحل اللاحقة التي تأثرت على الفور.

طلب بحث عن المسح

ابدأ من location معيّن يمثّل مركز التوزيع، وحدِّد المستودع المخزّن هناك، واطّلِع على السلع النهائية التي تتطلّبها.

# @title Impact of a storm on a DC

%%bigquery  --project=$PROJECT_ID --graph
Graph restaurant.bombod
match path1=(z:itemlocation)-[m:stored_at]->(dc:location) where dc.locationKey like '%DC-Sysco-Columbus-OH%'
match path2=(z:itemlocation)-[c:consists_of]->(b:itemlocation)
match path3=(b:itemlocation)-[n:makes]->(item:item)
optional match path4=(b)-[p:stored_at]->(q:location)
return to_json(path1) as path1, to_json(path2) as path2,to_json(path3) as path3, to_json(path4) as path4


الإخراج: تأثير العاصفة

9- حالة الاستخدام 3: سحب المنتج من السوق في المراحل اللاحقة

السيناريو: يُعلمك أحد المورّدين بدفعة معيّنة من المنتجات الملوّثة: طماطم ناضجة على الكرمة من المورّد. عليك العثور على جميع عناصر قائمة الطعام النهائية المتأثرة في المقاهي.

طلب بحث عن المسح

ابحث عن موقع المواد الخام الملوّثة، ثم نفِّذ عملية اجتياز للمسار تنتقل من المراحل اللاحقة إلى المراحل السابقة للعثور على السلع المتأثرة النهائية.

%%bigquery  --project=$PROJECT_ID --graph
Graph restaurant.bombod
match path1=(a:itemlocation)-[c:consists_of]->(b:itemlocation)-[e:makes]->(f:item) where f.itemKey like '%Tomato%'
return to_json(path1) as result

يحدّد هذا الطلب جميع السلع التي تتطابق مع النمط "طماطم" والتي تتشابك مع العلاقة في المراحل السابقة، ما يجعلها عملية ربط فعّالة تنتشر لاكتشاف عناصر المقهى التي يجب سحبها.

الإخراج: تأثير الطماطم الفاسدة بعد بيع المنتج

10. تنظيف

احذف الموارد بعد إكمال خطوات الشرح لتجنُّب أي رسوم متبقية في مساحة العمل.

DROP SCHEMA `restaurant` CASCADE;

11. الخاتمة

تهانينا! لقد أنشأت نموذجًا لسلسلة إمداد ونفّذت تحليل التأثير باستخدام BigQuery Graph.

الخاتمة

لقد تعلّمتَ ما يلي:

  1. الإعلان عن العلاقات العلائقية التي تركّز على الرسم البياني باستخدام المفاتيح الأساسية/الخارجية
  2. إنشاء رسم بياني للخصائص موحّد
  3. التنقّل بكفاءة في العلاقات المتعدّدة العُقد باستخدام منطق اجتياز طلبات البحث في الرسم البياني

لاكتساب المزيد من المعلومات حول بنية الرسم البياني، انتقِل إلى مستندات Google Cloud.