1. مقدمة
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية إجراء بحث مختلط في AlloyDB باستخدام إضافة RUM (طريقة تعديل الترتيب) وفهرس ScaNN (البحث عن أقرب جار قابل للتوسيع). هذا الدرس التطبيقي هو جزء من مجموعة دروس تطبيقية مخصّصة لميزات AlloyDB AI. يمكنك الاطّلاع على مزيد من المعلومات في صفحة AlloyDB AI ضمن المستندات.
المتطلبات الأساسية
- فهم أساسي لـ Google Cloud وConsole
- مهارات أساسية في واجهة سطر الأوامر وGoogle Shell
ما ستتعلمه
- كيفية نشر مجموعة AlloyDB ومثيل أساسي
- كيفية الاتصال بـ AlloyDB من جهاز افتراضي على Google Compute Engine
- كيفية إنشاء قاعدة بيانات وتفعيل AlloyDB AI
- كيفية تحميل البيانات إلى قاعدة البيانات
- كيفية استخدام AlloyDB Studio
- إنشاء تضمينات باستخدام Vertex AI
- كيفية إنشاء فهرس متّجه ScaNN لتحسين البحث المستند إلى المتّجهات
- كيفية تفعيل إضافة RUM واستخدامها للبحث عن النص الكامل
- إجراء بحث مختلط من خلال الجمع بين البحث عن النص الكامل والبحث المتّجه ودمج الترتيب التبادلي (RRF)
المتطلبات
- حساب على Google Cloud ومشروع على Google Cloud
- متصفّح ويب، مثل Chrome
2. الإعداد والمتطلبات
إعداد المشروع
سجِّل الدخول إلى Google Cloud Console. إذا لم يكن لديك حساب على Gmail أو Google Workspace، عليك إنشاء حساب.
استخدام حساب شخصي بدلاً من حساب تديره المؤسسة التعليمية أو حساب تابع للعمل.
إنشاء مشروع على Google Cloud
- في Google Cloud Console، في صفحة اختيار المشروع، اختَر مشروعًا على Google Cloud أو أنشِئ مشروعًا.
- تأكَّد من تفعيل الفوترة لمشروعك على السحابة الإلكترونية. كيفية التحقّق مما إذا كانت الفوترة مفعَّلة في مشروع
تفعيل الفوترة
لتفعيل الفوترة، لديك خياران. يمكنك استخدام حساب الفوترة الشخصي أو تحصيل قيمة الرصيد باتّباع الخطوات التالية.
إعداد حساب فوترة شخصي
إذا أعددت الفوترة باستخدام أرصدة Google Cloud، يمكنك تخطّي هذه الخطوة.
لإعداد حساب فوترة شخصي، انتقِل إلى هنا لتفعيل الفوترة في Cloud Console.
بعض الملاحظات:
- يجب أن تبلغ تكلفة إكمال هذا المختبر أقل من 3 دولارات أمريكية من موارد السحابة الإلكترونية.
- يمكنك اتّباع الخطوات في نهاية هذا المختبر لحذف الموارد وتجنُّب المزيد من الرسوم.
- يمكن للمستخدمين الجدد الاستفادة من فترة تجريبية مجانية بقيمة 300 دولار أمريكي.
بدء Cloud Shell
على الرغم من إمكانية تشغيل Google Cloud عن بُعد من الكمبيوتر المحمول، ستستخدم في هذا الدرس التطبيقي حول الترميز Google Cloud Shell، وهي بيئة سطر أوامر تعمل في السحابة الإلكترونية.
Cloud Shell هي بيئة سطر أوامر تعمل في Google Cloud ومحمّلة مسبقًا بالأدوات اللازمة.
- انقر على تفعيل 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
يتم تحميل هذه الآلة الافتراضية مزوّدة بكل أدوات التطوير التي ستحتاج إليها. توفّر هذه الخدمة دليلًا منزليًا ثابتًا بسعة 5 غيغابايت، وتعمل على Google Cloud، ما يؤدي إلى تحسين أداء الشبكة والمصادقة بشكل كبير. يمكن إكمال جميع المهام في هذا الدرس العملي ضمن المتصفّح. لست بحاجة إلى تثبيت أي تطبيق.
3- قبل البدء
تفعيل واجهة برمجة التطبيقات
إخراج:
لاستخدام AlloyDB وCompute Engine وخدمات الشبكات وVertex AI، عليك تفعيل واجهات برمجة التطبيقات الخاصة بها في مشروعك على Google Cloud.
تفعيل واجهات برمجة التطبيقات
داخل Cloud Shell في الوحدة الطرفية، تأكَّد من إعداد رقم تعريف مشروعك:
gcloud config set project [YOUR-PROJECT-ID]
اضبط متغيّر البيئة PROJECT_ID:
PROJECT_ID=$(gcloud config get-value project)
فعِّل جميع واجهات برمجة التطبيقات اللازمة:
gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com
الناتج المتوقّع
student@cloudshell:~ (test-project-001-402417)$ gcloud config set project test-project-001-402417
Updated property [core/project].
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project)
Your active configuration is: [cloudshell-14650]
student@cloudshell:~ (test-project-001-402417)$
student@cloudshell:~ (test-project-001-402417)$ gcloud services enable alloydb.googleapis.com \
compute.googleapis.com \
cloudresourcemanager.googleapis.com \
servicenetworking.googleapis.com \
aiplatform.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.
لمحة عن واجهات برمجة التطبيقات
- تتيح لك واجهة AlloyDB API (
alloydb.googleapis.com) إنشاء مجموعات AlloyDB for PostgreSQL وإدارتها وتوسيع نطاقها. توفّر هذه الخدمة قاعدة بيانات مُدارة بالكامل ومتوافقة مع PostgreSQL ومصمَّمة لتلبية متطلبات مهام العمل التحليلية والمعاملات على مستوى المؤسسة. - تتيح لك Compute Engine API (
compute.googleapis.com) إنشاء الأجهزة الافتراضية والأقراص الثابتة وإعدادات الشبكة وإدارتها. توفّر هذه المنطقة الأساس المطلوب لتشغيل أحجام العمل واستضافة البنية التحتية الأساسية للعديد من الخدمات المُدارة. - تتيح لك Cloud Resource Manager API (
cloudresourcemanager.googleapis.com) إدارة البيانات الوصفية وإعدادات مشروعك على السحابة الإلكترونية من Google آليًا. تتيح لك هذه الخدمة تنظيم الموارد والتعامل مع سياسات "إدارة الهوية والوصول" (IAM) والتحقّق من صحة الأذونات في جميع مستويات تسلسل المشاريع. - تتيح لك Service Networking API (
servicenetworking.googleapis.com) إمكانية إعداد الاتصال الخاص بين شبكة السحابة الافتراضية الخاصة (VPC) وخدمات Google المُدارة بشكل آلي. وهو مطلوب تحديدًا لإتاحة الوصول إلى عناوين IP الخاصة لخدمات مثل AlloyDB حتى تتمكّن من التواصل بأمان مع مواردك الأخرى. - تتيح Vertex AI API (
aiplatform.googleapis.com) لتطبيقاتك إنشاء نماذج تعلُّم الآلة ونشرها وتوسيع نطاقها. توفّر هذه المنصة واجهة موحّدة لجميع خدمات الذكاء الاصطناعي من Google Cloud، بما في ذلك إمكانية الوصول إلى نماذج الذكاء الاصطناعي التوليدي (مثل Gemini) وتدريب النماذج المخصّصة.
يمكنك اختياريًا ضبط منطقتك التلقائية لاستخدام نماذج التضمين في Vertex AI. مزيد من المعلومات حول المواقع الجغرافية المتاحة لـ Vertex AI في المثال، نستخدم المنطقة us-central1.
gcloud config set compute/region us-central1
4. تفعيل AlloyDB
قبل إنشاء مجموعة AlloyDB، نحتاج إلى نطاق عناوين IP خاصة متاح في شبكة السحابة الافتراضية الخاصة (VPC) لاستخدامه في مثيل AlloyDB المستقبلي. إذا لم يكن لدينا، علينا إنشاؤه وتعيينه ليتم استخدامه من قِبل خدمات Google الداخلية، وبعد ذلك سنتمكّن من إنشاء المجموعة والآلة الافتراضية.
إنشاء نطاق عناوين IP خاصة
علينا ضبط إعدادات الوصول إلى الخدمات الخاصة في شبكة السحابة الإلكترونية الخاصة الافتراضية (VPC) لخدمة AlloyDB. الافتراض هنا هو أنّ لدينا شبكة VPC "تلقائية" في المشروع وسيتم استخدامها في جميع الإجراءات.
أنشئ نطاق عناوين IP الخاصة:
gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
إنشاء اتصال خاص باستخدام نطاق عناوين IP المخصّص:
gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ gcloud compute addresses create psa-range \
--global \
--purpose=VPC_PEERING \
--prefix-length=24 \
--description="VPC private service access" \
--network=default
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/global/addresses/psa-range].
student@cloudshell:~ (test-project-402417)$ gcloud services vpc-peerings connect \
--service=servicenetworking.googleapis.com \
--ranges=psa-range \
--network=default
Operation "operations/pssn.p24-4470404856-595e209f-19b7-4669-8a71-cbd45de8ba66" finished successfully.
student@cloudshell:~ (test-project-402417)$
إنشاء مجموعة AlloyDB
في هذا القسم، سننشئ مجموعة AlloyDB في المنطقة us-central1.
حدِّد كلمة مرور لمستخدم postgres. يمكنك تحديد كلمة المرور الخاصة بك أو استخدام دالة عشوائية لإنشاء كلمة مرور
export PGPASSWORD=`openssl rand -hex 12`
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ export PGPASSWORD=`openssl rand -hex 12`
دوِّن كلمة مرور PostgreSQL لاستخدامها في المستقبل.
echo $PGPASSWORD
ستحتاج إلى كلمة المرور هذه في المستقبل للاتصال بالجهاز الظاهري بصفتك مستخدم postgres. أقترح عليك تدوينها أو نسخها في مكان ما لتتمكّن من استخدامها لاحقًا.
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-402417)$ echo $PGPASSWORD bbefbfde7601985b0dee5723
إنشاء مجموعة AlloyDB
حدِّد المنطقة واسم مجموعة AlloyDB. سنستخدم المنطقة us-central1 وalloydb-hybrid-search كاسم مجموعة:
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
نفِّذ الأمر التالي لإنشاء المجموعة:
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
الناتج المتوقّع في وحدة التحكّم:
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud alloydb clusters create $ADBCLUSTER \
--password=$PGPASSWORD \
--network=default \
--region=$REGION
Operation ID: operation-1697655441138-6080235852277-9e7f04f5-2012fce4
Creating cluster...done.
أنشئ مثيلاً أساسيًا من AlloyDB لمجموعتك في جلسة Cloud Shell نفسها. في حال انقطاع الاتصال، عليك تحديد متغيرات بيئة اسم المنطقة واسم المجموعة مرة أخرى.
gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--cluster=$ADBCLUSTER
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (alloydb-hybrid-search)$ gcloud alloydb instances create $ADBCLUSTER-pr \
--instance-type=PRIMARY \
--cpu-count=2 \
--region=$REGION \
--availability-type ZONAL \
--cluster=$ADBCLUSTER
Operation ID: operation-1697659203545-6080315c6e8ee-391805db-25852721
Creating instance...done.
5- الربط بـ AlloyDB
يتم نشر AlloyDB باستخدام اتصال خاص فقط، لذلك نحتاج إلى جهاز افتراضي مثبَّت عليه برنامج PostgreSQL للتعامل مع قاعدة البيانات.
نشر جهاز GCE افتراضي
أنشئ جهازًا افتراضيًا على GCE في المنطقة نفسها والشبكة الافتراضية الخاصة (VPC) نفسها التي تضم مجموعة AlloyDB.
في Cloud Shell، نفِّذ ما يلي:
export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE \
--create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
--scopes=https://www.googleapis.com/auth/cloud-platform
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (alloydb-hybrid-search)$ export ZONE=us-central1-a
student@cloudshell:~ (talloydb-hybrid-search)$ export ZONE=us-central1-a
gcloud compute instances create instance-1 \
--zone=$ZONE \
--create-disk=auto-delete=yes,boot=yes,image=projects/debian-cloud/global/images/$(gcloud compute images list --filter="family=debian-12 AND family!=debian-12-arm64" --format="value(name)") \
--scopes=https://www.googleapis.com/auth/cloud-platform
Created [https://www.googleapis.com/compute/v1/projects/test-project-402417/zones/us-central1-a/instances/instance-1].
NAME: instance-1
ZONE: us-central1-a
MACHINE_TYPE: n1-standard-1
PREEMPTIBLE:
INTERNAL_IP: 10.128.0.2
EXTERNAL_IP: 34.71.192.233
STATUS: RUNNING
تثبيت Postgres Client
تثبيت برنامج عميل PostgreSQL على الجهاز الافتراضي الذي تم نشره
اتّصِل بالجهاز الافتراضي:
gcloud compute ssh instance-1 --zone=us-central1-a
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (alloydb-hybrid-search)$ gcloud compute ssh instance-1 --zone=us-central1-a Updating project ssh metadata...working..Updated [https://www.googleapis.com/compute/v1/projects/alloydb-hybrid-search]. Updating project ssh metadata...done. Waiting for SSH key to propagate. Warning: Permanently added 'compute.5110295539541121102' (ECDSA) to the list of known hosts. Linux instance-1.us-central1-a.c.gleb-test-short-001-418811.internal 6.1.0-18-cloud-amd64 #1 SMP PREEMPT_DYNAMIC Debian 6.1.76-1 (2024-02-01) x86_64 The programs included with the Debian GNU/Linux system are free software; the exact distribution terms for each program are described in the individual files in /usr/share/doc/*/copyright. Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent permitted by applicable law. student@instance-1:~$
ثبِّت البرنامج الذي يشغّل الأمر داخل الجهاز الافتراضي:
sudo apt-get update
sudo apt-get install --yes postgresql-client
الناتج المتوقّع في وحدة التحكّم:
student@instance-1:~$ sudo apt-get update sudo apt-get install --yes postgresql-client Get:1 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable InRelease [5146 B] Get:2 https://packages.cloud.google.com/apt cloud-sdk-bullseye InRelease [6406 B] Hit:3 https://deb.debian.org/debian bullseye InRelease Get:4 https://deb.debian.org/debian-security bullseye-security InRelease [48.4 kB] Get:5 https://packages.cloud.google.com/apt google-compute-engine-bullseye-stable/main amd64 Packages [1930 B] Get:6 https://deb.debian.org/debian bullseye-updates InRelease [44.1 kB] Get:7 https://deb.debian.org/debian bullseye-backports InRelease [49.0 kB] ...redacted... update-alternatives: using /usr/share/postgresql/13/man/man1/psql.1.gz to provide /usr/share/man/man1/psql.1.gz (psql.1.gz) in auto mode Setting up postgresql-client (13+225) ... Processing triggers for man-db (2.9.4-2) ... Processing triggers for libc-bin (2.31-13+deb11u7) ...
الربط بالجهاز الافتراضي
اتّصِل بالمثيل الأساسي من الجهاز الافتراضي باستخدام psql.
في علامة التبويب نفسها في Cloud Shell التي تم فيها فتح جلسة SSH على الجهاز الظاهري instance-1
استخدِم قيمة كلمة مرور AlloyDB (PGPASSWORD) ومعرّف مجموعة AlloyDB للاتصال بـ AlloyDB من الجهاز الافتراضي على GCE:
export PGPASSWORD=<Noted password>
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)")
psql "host=$INSTANCE_IP user=postgres sslmode=require"
الناتج المتوقّع في وحدة التحكّم:
student@instance-1:~$ export PGPASSWORD=CQhOi5OygD4ps6ty student@instance-1:~$ ADBCLUSTER=alloydb-aip-01 student@instance-1:~$ REGION=us-central1 student@instance-1:~$ INSTANCE_IP=$(gcloud alloydb instances describe $ADBCLUSTER-pr --cluster=$ADBCLUSTER --region=$REGION --format="value(ipAddress)") gleb@instance-1:~$ psql "host=$INSTANCE_IP user=postgres sslmode=require" psql (15.6 (Debian 15.6-0+deb12u1), server 15.5) SSL connection (protocol: TLSv1.3, cipher: TLS_AES_256_GCM_SHA384, compression: off) Type "help" for help. postgres=>
أغلِق جلسة psql:
exit
6. إعداد قاعدة البيانات
علينا إنشاء قاعدة بيانات وتفعيل عملية التكامل مع Vertex AI وإنشاء عناصر قاعدة البيانات واستيراد البيانات.
منح الأذونات اللازمة إلى AlloyDB
أضِف أذونات Vertex AI إلى وكيل خدمة AlloyDB.
افتح علامة تبويب أخرى في Cloud Shell باستخدام الرمز "+" في أعلى الصفحة.

في علامة تبويب Cloud Shell الجديدة، نفِّذ ما يلي:
PROJECT_ID=$(gcloud config get-value project)
gcloud projects add-iam-policy-binding $PROJECT_ID \
--member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \
--role="roles/aiplatform.user"
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ PROJECT_ID=$(gcloud config get-value project) Your active configuration is: [cloudshell-11039] student@cloudshell:~ (test-project-001-402417)$ gcloud projects add-iam-policy-binding $PROJECT_ID \ --member="serviceAccount:service-$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")@gcp-sa-alloydb.iam.gserviceaccount.com" \ --role="roles/aiplatform.user" Updated IAM policy for project [test-project-001-402417]. bindings: - members: - serviceAccount:service-4470404856@gcp-sa-alloydb.iam.gserviceaccount.com role: roles/aiplatform.user - members: ... etag: BwYIEbe_Z3U= version: 1
أغلِق علامة التبويب من خلال تنفيذ الأمر "exit" في علامة التبويب:
exit
إنشاء قاعدة بيانات
أنشئ قاعدة بيانات باسم quickstart.
في جلسة الجهاز الافتراضي على GCE، نفِّذ ما يلي:
إنشاء قاعدة بيانات:
psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db"
الناتج المتوقّع في وحدة التحكّم:
student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres" -c "CREATE DATABASE quickstart_db" CREATE DATABASE student@instance-1:~$
تفعيل ميزة "التكامل مع Vertex AI"
فعِّل عملية دمج Vertex AI وإضافات pgvector في قاعدة البيانات.
في الجهاز الافتراضي على GCE، نفِّذ ما يلي:
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE"
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector"
الناتج المتوقّع في وحدة التحكّم:
student@instance-1:~$ psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS google_ml_integration CASCADE" psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "CREATE EXTENSION IF NOT EXISTS vector" CREATE EXTENSION CREATE EXTENSION student@instance-1:~$
استيراد البيانات
نزِّل البيانات المُعدّة واستوردها إلى قاعدة البيانات الجديدة.
في الجهاز الافتراضي على GCE، نفِّذ ما يلي:
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header"
gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header"
الناتج المتوقّع في وحدة التحكّم:
student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_demo_schema.sql |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" SET SET SET SET SET set_config ------------ (1 row) SET SET SET SET SET SET CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE TABLE ALTER TABLE CREATE SEQUENCE ALTER TABLE ALTER SEQUENCE ALTER TABLE ALTER TABLE ALTER TABLE student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_products from stdin csv header" COPY 941 student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_inventory.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_inventory from stdin csv header" COPY 263861 student@instance-1:~$ gcloud storage cat gs://cloud-training/gcc/gcc-tech-004/cymbal_stores.csv |psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db" -c "\copy cymbal_stores from stdin csv header" COPY 4654 student@instance-1:~$
7. إنشاء متجهات التضمين
بعد استيراد البيانات، نحصل على الجداول التالية: cymbal_products الذي يخزّن معلومات حول المنتجات، وcymbal_inventory الذي يتتبّع مخزون السلع في كل متجر، وcymbal_stores الذي يضم قائمة بالمتاجر. لإجراء بحث دلالي في منتجاتنا، نحتاج إلى إنشاء تضمينات متجهة لأوصاف منتجاتنا باستخدام الدالة initialize_embeddings. سنستخدم عملية دمج Vertex AI لاحتساب بيانات المتّجهات استنادًا إلى أوصاف منتجاتنا وإضافتها إلى الجدول. يمكنك الاطّلاع على مزيد من المعلومات حول التكنولوجيا المستخدَمة في المستندات.
لاستخدام عملية الدمج، اتّصِل بقاعدة البيانات باستخدام psql من جهازك الافتراضي باستخدام عنوان IP لمثيل AlloyDB وكلمة مرور postgres:
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
تحقَّق من إصدار إضافة google_ml_integration.
SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration';
يجب أن يكون الإصدار 1.5.2 أو إصدارًا أحدث. في ما يلي مثال على الناتج:
quickstart_db=> SELECT extversion FROM pg_extension WHERE extname = 'google_ml_integration'; extversion ------------ 1.5.2 (1 row)
يجب أن يكون الإصدار التلقائي 1.5.2 أو إصدارًا أحدث، ولكن إذا كان مثبّتًا على جهازك إصدار أقدم، من المحتمل أن تحتاج إلى تحديثه. تحقَّق مما إذا كانت الصيانة غير مفعَّلة للآلة الافتراضية.
سنستخدم ميزة إنشاء التضمينات المجمّعة لتحسين الكفاءة. يمكنك الاطّلاع على المزيد من المعلومات حول خيارات وأساليب إنشاء التضمينات المختلفة في هذا الدليل. لاستخدام التضمين المجمّع، علينا تفعيل goole_ml_integration.enable_faster_embedding_generation
show google_ml_integration.enable_faster_embedding_generation;
إذا كانت العلامة في الموضع الصحيح، سيبدو الناتج المتوقّع على النحو التالي:
quickstart_db=> show google_ml_integration.enable_faster_embedding_generation; google_ml_integration.enable_faster_embedding_generation ---------------------------------------------------------- on (1 row)
ولكن إذا ظهرت الحالة "إيقاف"، علينا تحديث الجهاز الظاهري. يمكنك إجراء ذلك باستخدام وحدة تحكّم الويب أو أمر gcloud كما هو موضّح في المستندات. في ما يلي كيفية إجراء ذلك باستخدام أمر gcloud:
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags google_ml_integration.enable_faster_embedding_generation=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
قد يستغرق ذلك بضع دقائق، ولكن من المفترض أن يتم تبديل قيمة العلامة إلى "مفعَّل" في النهاية. بعد ذلك، يمكنك المتابعة إلى الخطوات التالية.
psql "host=$INSTANCE_IP user=postgres dbname=quickstart_db"
في جلسة psql المرتبطة بقاعدة البيانات، أنشئ عمودًا جديدًا لتخزين التضمينات في cymbal_products
ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768);
الناتج المتوقّع في وحدة التحكّم:
quickstart_db=> ALTER TABLE cymbal_products ADD COLUMN product_embedding vector(768); ALTER TABLE quickstart_db=>
أخيرًا، نريد أيضًا أن يتم تعديل عمليات التضمين عند تغيير قيم الأعمدة من خلال تضمين الوسيطة incremental_refresh_mode في استدعاء الدالة. يؤدي ذلك إلى زيادة الحمل على قاعدة البيانات، ولكنّنا نعتبر ذلك حلاً وسطًا مقبولاً من أجل إبقاء عمليات التضمين متزامنة مع المحتوى تلقائيًا. إذا أردت تعديل عمليات التضمين يدويًا، يمكنك العثور على التعليمات في المستندات.
بعد تجميع كل ما سبق وإنشاء التضمينات، نستخدم الدالة initialize_embeddings ونمرّر batch_size بقيمة 50 كإشارة إلى الدُفعة ونضبط incremental_refresh_mode على transactional
CALL ai.initialize_embeddings(
model_id => 'text-embedding-005',
table_name => 'cymbal_products',
content_column => 'product_description',
embedding_column => 'product_embedding',
batch_size => 50,
incremental_refresh_mode => 'transactional'
);
والآن، إذا أدرجنا صفًا جديدًا في الجدول مع القيمة NULL للعمود product_embedding
INSERT INTO "cymbal_products" ("uniq_id", "crawl_timestamp", "product_url", "product_name", "product_description", "list_price", "sale_price", "brand", "item_number", "gtin", "package_size", "category", "postal_code", "available", "product_embedding") VALUES ('fd604542e04b470f9e6348e640cff794', NOW(), 'https://example.com/new_product', 'New Cymbal Product', 'This is a new cymbal product description.', 199.99, 149.99, 'Example Brand', 'EB123', '1234567890', 'Single', 'Cymbals', '12345', TRUE, NULL);
الآن، عندما نطلب عرض الصف الذي أدرجناه للتو، سنلاحظ أنّه يتم تعديل العمود product_embedding تلقائيًا.
SELECT uniq_id, (product_embedding::real[])[1:5] as product_embedding FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
يجب أن تبدو المخرجات على النحو التالي:
quickstart_db=> SELECT uniq_id,(product_embedding::real[])[1:5] as product_embedding FROM cymbal_products WHERE uniq_id='fd604542e04b470f9e6348e640cff794';
uniq_id | product_embedding
----------------------------------+---------------------------------------------------------------
fd604542e04b470f9e6348e640cff794 | {0.015003494,-0.005349732,-0.059790313,-0.0087091,-0.0271452}
(1 row)
Time: 3.295 ms
8. إنشاء فهرس متجهات
لتحسين أداء البحث المتّجهي، سنضيف فهرس ScaNN.
إنشاء فهرس ScaNN
لإنشاء فهرس SCANN، علينا تفعيل إضافة أخرى. تقدّم الإضافة alloydb_scann واجهة للعمل مع فهرس المتجهات من النوع ANN باستخدام خوارزمية ScaNN من Google.
CREATE EXTENSION IF NOT EXISTS alloydb_scann;
الناتج المتوقّع:
quickstart_db=> CREATE EXTENSION IF NOT EXISTS alloydb_scann; CREATE EXTENSION Time: 27.468 ms quickstart_db=>
يمكن إنشاء الفهرس في الوضع MANUAL أو AUTO. يكون الوضع MANUAL مفعّلاً تلقائيًا ويمكنك إنشاء فهرس والاحتفاظ به كأي فهرس آخر. ولكن إذا فعّلت الوضع AUTO، ستتمكّن من إنشاء الفهرس الذي لا يتطلّب أي صيانة من جانبك. يمكنك الاطّلاع على تفاصيل حول جميع الخيارات في المستندات. في حالتنا، لا تتوفّر لدينا صفوف كافية لإنشاء الفهرس في الوضع AUTO، لذا سننشئه في الوضع MANUAL وسنضمّن مَعلمات الضبط. يمكنك الاطّلاع على معلومات حول ضبط مَعلمات الفهرس في المستندات.
يجب تفعيل العلامة scann.enable_preview_features حتى نتمكّن من تعديل معلَمات الضبط. في Cloudshell
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags scann.enable_preview_features=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
قد يستغرق ذلك بضع دقائق، ولكن من المفترض أن يتم تبديل قيمة العلامة إلى "مفعَّل" في النهاية. بعد ضبط العلامة، يمكننا العودة إلى جلسة psql على الجهاز الافتراضي وإنشاء الفهرس باستخدام مَعلمات الضبط.
CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products
USING scann (product_embedding cosine)
WITH (mode='MANUAL', num_leaves=31, max_num_levels = 2);
الناتج المتوقّع:
quickstart_db=> CREATE INDEX cymbal_products_embeddings_scann ON cymbal_products USING scann (product_embedding cosine) WITH (num_leaves=31, max_num_levels = 2); CREATE INDEX quickstart_db=>
فحص استخدام الفهرس
يمكننا الآن تشغيل طلب البحث عن المتجهات في وضع EXPLAIN والتحقّق من استخدام الفهرس.
EXPLAIN (analyze)
WITH trees as (
SELECT
cp.product_name,
left(cp.product_description,80) as description,
cp.sale_price,
cs.zip_code,
cp.uniq_id as product_id
FROM
cymbal_products cp
JOIN cymbal_inventory ci on
ci.uniq_id=cp.uniq_id
JOIN cymbal_stores cs on
cs.store_id=ci.store_id
AND ci.inventory>0
AND cs.store_id = 1583
ORDER BY
(cp.product_embedding <=> embedding('text-embedding-005','What kind of fruit trees grow well here?')::vector) ASC
LIMIT 1)
SELECT json_agg(trees) FROM trees;
الناتج المتوقّع (تم إخفاء بعض المعلومات لتوضيح الصورة):
... Aggregate (cost=16.59..16.60 rows=1 width=32) (actual time=2.875..2.877 rows=1 loops=1) -> Subquery Scan on trees (cost=8.42..16.59 rows=1 width=142) (actual time=2.860..2.862 rows=1 loops=1) -> Limit (cost=8.42..16.58 rows=1 width=158) (actual time=2.855..2.856 rows=1 loops=1) -> Nested Loop (cost=8.42..6489.19 rows=794 width=158) (actual time=2.854..2.855 rows=1 loops=1) -> Nested Loop (cost=8.13..6466.99 rows=794 width=938) (actual time=2.742..2.743 rows=1 loops=1) -> Index Scan using cymbal_products_embeddings_scann on cymbal_products cp (cost=7.71..111.99 rows=876 width=934) (actual time=2.724..2.724 rows=1 loops=1) Order By: (embedding <=> '[0.008864171,0.03693164,-0.024245683,-0.00355923,0.0055611245,0.015985578,...<redacted>...5685,-0.03914233,-0.018452475,0.00826032,-0.07372604]'::vector) ...
من الناتج، يمكننا أن نرى بوضوح أنّ طلب البحث كان يستخدم "Index Scan using cymbal_products_embeddings_scann on cymbal_products".
9- فهرس البحث في النص الكامل
تتيح AlloyDB جميع أنواع الفهارس للبحث عن نص كامل التي تتيحها PostgreSQL الأصلية. يعتمد اختيار الفهرس على الموازنة بين سرعة البحث ومدة تصميم الفهرس وسرعة التعديل ووظائف البحث المحدّدة المطلوبة، مثل البحث عن عبارة أو ترتيب النتائج حسب الصلة بموضوع البحث.
في مثالنا، سنستخدم إضافة RUM لإجراء عمليات بحث أكثر فعالية عن النص الكامل. تحسّن RUM فهارس GIN العادية من خلال تخزين المعلومات الموضعية مباشرةً في الفهرس، ما يتيح لك إجراء عمليات بحث أسرع عن العبارات وترتيب النتائج حسب الصلة بدون الوصول إلى بيانات الجدول.
يمكنك استخدام AlloyDB Studio أو مواصلة استخدام أداة psql لتفعيل إضافة rum.
إنشاء فهرس RUM
CREATE EXTENSION IF NOT EXISTS rum;
للبحث في أوصاف المنتجات ضمن جدول cymbal_products، علينا إنشاء عمود يخزّن وصف المنتج كـ tsvector. يخزّن هذا العمود النص المعالَج تلقائيًا ويحسّن أداء طلب البحث.
ALTER TABLE cymbal_products
ADD COLUMN product_search_vector tsvector
GENERATED ALWAYS AS (to_tsvector('english', product_description)) STORED;
يمكننا الآن إنشاء فهرس جديد لبيانات تجربة المستخدم الحقيقية للعمود product_search_vector.
CREATE INDEX cymbal_products_rum
ON cymbal_products
USING rum (product_search_vector rum_tsvector_ops);
للاستعلام عن الجدول باستخدام الفهرس، شغِّل طلب البحث التالي الذي يبحث عن تطابقات لعبارة "شجرة الكرز". يحسب عامل التشغيل <=> درجة الصلة أو المسافة بين المستند وطلب البحث مباشرةً من الفهرس.
SELECT product_name, product_description
FROM cymbal_products
WHERE product_search_vector @@ to_tsquery('english', 'cherry <-> tree')
ORDER BY product_search_vector <=> to_tsquery('english', 'cherry <-> tree');
10. إجراء بحث مختلط
تتيح لك الدالة google_vector_utils.hybrid_search() الجمع بين نتائج من أنواع بحث متعددة، مثل البحث المتّجه والبحث في النص الكامل. تدمج الدالة النتائج المرتبة من كل مكوّن من مكوّنات البحث في قائمة واحدة موحّدة باستخدام خوارزمية دمج الترتيب المتبادل (RRF). يقدّم هذا الأسلوب نتائج أكثر صلة من نوع بحث واحد فقط.
تنشئ الدالة hybrid_search() استعلام SQL واحدًا وتنفّذه بشكل ديناميكي. تنشئ هذه الدالة تعبير جدول مشتركًا (CTE) لكل مكوّن بحث تحدّده. بعد ذلك، تجمع الدالة النتائج من جميع تعبيرات CTE وتحسب درجة RRF نهائية لكل مستند لإنشاء قائمة موحّدة ومرتّبة.
لاستخدام الدالة، يجب تفعيل enable_preview_ai_functions في المثيل الأساسي. نفِّذ الأمر التالي في cloudshell
export PROJECT_ID=$(gcloud config get-value project)
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
gcloud beta alloydb instances update $ADBCLUSTER-pr \
--database-flags google_ml_integration.enable_preview_ai_functions=on \
--region=$REGION \
--cluster=$ADBCLUSTER \
--project=$PROJECT_ID \
--update-mode=FORCE_APPLY
يجمع طلب البحث التالي بين سؤال البحث المستند إلى المتجهات السابق وسؤال البحث عن النص الكامل. هذا مثال بسيط جدًا على طلب بحث مختلط، ويمكنك تجربة طلب بحث أكثر تعقيدًا، مثل استخدام "أشجار أطول من منزل" في مكوّن البحث المتّجه و "كاليفورنيا" في مكوّن البحث النصي الكامل.
SELECT score, id, p.product_name
FROM ai.hybrid_search(
search_inputs => ARRAY[
'{
"data_type": "vector",
"table_name": "cymbal_products",
"key_column": "uniq_id",
"vec_column": "product_embedding",
"distance_operator": "public.<=>",
"limit": 5,
"query_vector": "ai.embedding(''text-embedding-005'', ''cherry'')::vector"
}'::JSONB,
'{
"data_type": "text",
"table_name": "cymbal_products",
"key_column": "uniq_id",
"text_column": "product_search_vector",
"limit": 5,
"ranking_function": "<=>",
"query_text_input": "tree"
}'::JSONB
]
) JOIN cymbal_products p ON id = p.uniq_id;
الناتج المتوقّع
"score","id","product_name" "0.00819672631147241","d536e9e823296a2eba198e52dd23e712","Cherry Tree" "0.015873015873015872","23e41a71d63d8bbc9bdfa1d118cfddc5","Apple Tree" "0.00819672631147241","dc789a2f87b142e94e6e325689482af9","Oak Tree" "0.008064521129029258","f5c70d62ccf3118d73863bf3b17edcbe","Cypress Tree" "0.008064521129029258","b70c44b1a38c0a2329fa583c9109a80f","Peach Tree"
في النتائج، ستجد id وهو key_column المحدّد، وscore هي القيمة النهائية التي تحسبها RRF. Reciprocal Rank Fusion (RRF) هي خوارزمية تستند إلى الترتيب وتجمع قوائم متعدّدة مرتّبة لنتائج البحث في قائمة واحدة مرتّبة من خلال منح كل مستند درجة. تستند هذه النتيجة إلى الترتيب التبادلي لـ RRF في جميع القوائم المساهمة، مع تلقّي المستندات ذات الترتيب الأعلى مساهمة أكبر. باستخدام include_json_output => true في المَعلمة، سيتم عرض عمود detail_json يحتوي على تفصيل لعملية احتساب النتيجة لكل مكوّن.
في حين أنّ البحث النصي الكامل هو الأفضل للعثور على عبارات محدّدة أو مطابقة تامة، يتفوّق البحث المتّجه في العثور على المرادفات والنية حتى عندما لا تتطابق الكلمات. من خلال دمج هاتين الطريقتين، يضمن البحث المختلط حصول المستخدمين على مجموعة قوية من النتائج الدقيقة حرفيًا والملائمة دلاليًا.
11. تنظيف البيئة
إتلاف مثيلات AlloyDB ومجموعة AlloyDB عند الانتهاء من الدرس التطبيقي
حذف مجموعة AlloyDB وجميع مثيلاتها
إذا سبق لك استخدام الإصدار التجريبي من AlloyDB لا تحذف المجموعة التجريبية إذا كنت تخطّط لاختبار ميزات اختبارية وموارد أخرى باستخدام المجموعة التجريبية. لن تتمكّن من إنشاء مجموعة تجريبية أخرى في المشروع نفسه.
يتم إيقاف المجموعة باستخدام الخيار force الذي يؤدي أيضًا إلى حذف جميع المثيلات التابعة للمجموعة.
في Cloud Shell، حدِّد متغيرات المشروع والبيئة إذا تم قطع الاتصال وفقدت جميع الإعدادات السابقة:
gcloud config set project <your project id>
export REGION=us-central1
export ADBCLUSTER=alloydb-hybrid-search
export PROJECT_ID=$(gcloud config get-value project)
احذف المجموعة:
gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ gcloud alloydb clusters delete $ADBCLUSTER --region=$REGION --force All of the cluster data will be lost when the cluster is deleted. Do you want to continue (Y/n)? Y Operation ID: operation-1697820178429-6082890a0b570-4a72f7e4-4c5df36f Deleting cluster...done.
حذف النُسخ الاحتياطية في AlloyDB
احذف جميع النُسخ الاحتياطية من AlloyDB للمجموعة:
for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ for i in $(gcloud alloydb backups list --filter="CLUSTER_NAME: projects/$PROJECT_ID/locations/$REGION/clusters/$ADBCLUSTER" --format="value(name)" --sort-by=~createTime) ; do gcloud alloydb backups delete $(basename $i) --region $REGION --quiet; done Operation ID: operation-1697826266108-60829fb7b5258-7f99dc0b-99f3c35f Deleting backup...done.
الآن يمكننا محو الجهاز الظاهري
حذف جهاز GCE الافتراضي
في Cloud Shell، نفِّذ ما يلي:
export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
الناتج المتوقّع في وحدة التحكّم:
student@cloudshell:~ (test-project-001-402417)$ export GCEVM=instance-1
export ZONE=us-central1-a
gcloud compute instances delete $GCEVM \
--zone=$ZONE \
--quiet
Deleted
12. تهانينا
تهانينا على إكمال هذا الدرس العملي.
المواضيع التي تناولناها
- كيفية نشر مجموعة AlloyDB ومثيل أساسي
- كيفية الاتصال بـ AlloyDB من جهاز افتراضي على Google Compute Engine
- كيفية إنشاء قاعدة بيانات وتفعيل AlloyDB AI
- كيفية تحميل البيانات إلى قاعدة البيانات
- كيفية استخدام AlloyDB Studio
- إنشاء تضمينات باستخدام Vertex AI
- كيفية إنشاء فهرس متّجه ScaNN لتحسين البحث المستند إلى المتّجهات
- كيفية تفعيل إضافة RUM واستخدامها للبحث عن النص الكامل
- إجراء بحث مختلط من خلال الجمع بين البحث عن النص الكامل والبحث المتّجه ودمج الترتيب التبادلي (RRF)