תחילת העבודה עם חיפוש היברידי ב-AlloyDB

1. מבוא

בשיעור Codelab הזה תלמדו איך לבצע חיפוש היברידי ב-AlloyDB באמצעות התוסף RUM (שיטת עדכון הדירוג) והאינדקס ScaNN (חיפוש שכנים קרובים שניתן להרחבה). שיעור ה-Lab הזה הוא חלק מאוסף שיעורי Lab שמוקדשים לתכונות של AlloyDB AI. מידע נוסף זמין בדף AlloyDB AI בתיעוד.

דרישות מוקדמות

  • הבנה בסיסית של Google Cloud Console
  • מיומנויות בסיסיות בממשק שורת הפקודה וב-Google Shell

מה תלמדו

  • איך פורסים אשכול AlloyDB ומופע ראשי
  • איך מתחברים ל-AlloyDB ממכונה וירטואלית של Google Compute Engine
  • איך יוצרים מסד נתונים ומפעילים את AlloyDB AI
  • איך טוענים נתונים למסד הנתונים
  • איך משתמשים ב-AlloyDB Studio
  • יצירת הטמעות באמצעות Vertex AI
  • איך ליצור אינדקס וקטורי של ScaNN כדי לשפר את החיפוש הווקטורי
  • איך יוצרים Foreign Data Wrapper ‏ (FDW) ל-Elasticsearch
  • ביצוע חיפוש היברידי על ידי שילוב של חיפוש סמנטי ב-AlloyDB עם חיפוש טקסט מלא ב-Elastic.

מה תצטרכו

  • חשבון Google Cloud ופרויקט Google Cloud
  • דפדפן אינטרנט כמו Chrome

2. הגדרה ודרישות

הגדרת פרויקט

נכנסים למסוף Google Cloud. אם עדיין אין לכם חשבון Gmail או Google Workspace, אתם צריכים ליצור חשבון.

משתמשים בחשבון לשימוש אישי במקום בחשבון לצורכי עבודה או בחשבון בית ספרי.

יצירת פרויקט ב-Google Cloud

  1. במסוף Google Cloud, בדף לבחירת הפרויקט, בוחרים פרויקט ב-Google Cloud או יוצרים פרויקט.
  2. הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. כך בודקים אם החיוב מופעל בפרויקט

הפעלת החיוב

יש שתי דרכים להפעיל את החיוב. אתם יכולים להשתמש בחשבון החיוב האישי שלכם או לממש את הקרדיטים באמצעות השלבים הבאים.

הגדרה של חשבון לחיוב לשימוש אישי

אם הגדרתם חיוב באמצעות קרדיטים ב-Google Cloud, אתם יכולים לדלג על השלב הזה.

כדי להגדיר חשבון לחיוב לשימוש אישי, עוברים לכאן כדי להפעיל את החיוב ב-Cloud Console.

הערות:

  • העלות של השלמת ה-Lab הזה במשאבי Cloud צריכה להיות פחות מ-3 דולר ארה"ב.
  • כדי להימנע מחיובים נוספים, אפשר למחוק את המשאבים בסיום ה-Lab.
  • משתמשים חדשים זכאים לתקופת ניסיון בחינם בשווי 300$.

מפעילים את Cloud Shell

אפשר להפעיל את Google Cloud מרחוק מהמחשב הנייד, אבל ב-Codelab הזה נשתמש ב-Google Cloud Shell, סביבת שורת פקודה שפועלת בענן.

Cloud Shell היא סביבת שורת פקודה שפועלת ב-Google Cloud וכוללת מראש את הכלים הנדרשים.

  1. לוחצים על Activate Cloud Shell בחלק העליון של מסוף Google Cloud.
  2. אחרי שמתחברים ל-Cloud Shell, מאמתים את האימות:
    gcloud auth list
    
  3. מוודאים שהפרויקט מוגדר:
    gcloud config get project
    
  4. אם הפרויקט לא מוגדר כמו שציפיתם, מגדירים אותו:
    export PROJECT_ID=<YOUR_PROJECT_ID>
    gcloud config set project $PROJECT_ID
    

המכונה הווירטואלית הזו כוללת את כל הכלים שדרושים למפתחים. יש בה ספריית בית בנפח מתמיד של 5GB והיא פועלת ב-Google Cloud, מה שמשפר מאוד את הביצועים והאימות ברשת. אפשר לבצע את כל העבודה ב-codelab הזה בדפדפן. לא צריך להתקין שום דבר.

3. לפני שמתחילים

הפעלת ה-API

פלט:

כדי להשתמש ב-AlloyDB, ב-Compute Engine, ב-Networking services וב-Vertex AI, צריך להפעיל את ממשקי ה-API שלהם בפרויקט Google Cloud.

הפעלת ממשקי ה-API

בטרמינל של Cloud Shell, מוודאים שמזהה הפרויקט מוגדר:

gcloud config set project [YOUR-PROJECT-ID]

מגדירים את משתנה הסביבה PROJECT_ID:

PROJECT_ID=$(gcloud config get-value project)

מפעילים את כל ממשקי ה-API הנדרשים:

gcloud services enable alloydb.googleapis.com \
                       compute.googleapis.com \
                       cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       aiplatform.googleapis.com \
                       secretmanager.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 \
                       secretmanager.googleapis.com
Operation "operations/acat.p2-4470404856-1f44ebd8-894e-4356-bea7-b84165a57442" finished successfully.

מבוא לממשקי ה-API

  • AlloyDB API‏ (alloydb.googleapis.com) מאפשר לכם ליצור ולנהל אשכולות של AlloyDB ל-PostgreSQL, ולשנות את גודלם. הוא מספק שירות מנוהל של מסד נתונים שתואם ל-PostgreSQL ומיועד לעומסי עבודה כבדים בטרנזקציות ובניתוחים בארגונים.
  • Compute Engine API‏ (compute.googleapis.com) מאפשר לכם ליצור ולנהל מכונות וירטואליות (VM), דיסקים לאחסון מתמיד והגדרות רשת. היא מספקת את הבסיס של תשתית כשירות (IaaS) שנדרש להפעלת עומסי העבודה ולאירוח התשתית הבסיסית של שירותים מנוהלים רבים.
  • Cloud Resource Manager API‏ (cloudresourcemanager.googleapis.com) מאפשר לכם לנהל באופן פרוגרמטי את המטא-נתונים וההגדרות של פרויקט Google Cloud. היא מאפשרת לכם לארגן משאבים, לטפל במדיניות של ניהול זהויות והרשאות גישה (IAM) ולאמת הרשאות בהיררכיית הפרויקט.
  • Service Networking API ‏ (servicenetworking.googleapis.com) מאפשר לכם להגדיר באופן אוטומטי קישוריות פרטית בין הרשת של הענן הווירטואלי הפרטי (VPC) שלכם לבין השירותים המנוהלים של Google. הוא נדרש במיוחד כדי ליצור גישה לכתובות IP פרטיות לשירותים כמו AlloyDB, כדי שהם יוכלו לתקשר בצורה מאובטחת עם המשאבים האחרים שלכם.
  • Vertex AI API‏ (aiplatform.googleapis.com) מאפשר לאפליקציות שלכם ליצור מודלים של למידת מכונה, לפרוס אותם ולבצע להם התאמה לעומס (scaling). הוא מספק ממשק מאוחד לכל שירותי ה-AI של Google Cloud, כולל גישה למודלים של AI גנרטיבי (כמו Gemini) ואימון מודלים בהתאמה אישית.
  • Secret Manager API‏ (secretmanager.googleapis.com) הוא שירות לניהול סודות ואישורים שמאפשר לאחסן ולנהל מידע אישי רגיש כמו מפתחות API, שמות משתמשים, סיסמאות, אישורים ועוד.

אפשר גם להגדיר את אזור ברירת המחדל לשימוש במודלים להטמעה של 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 \
    --export-custom-routes

הפלט הצפוי במסוף:

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
<generated password>

יצירת אשכול 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 מותקן כדי לעבוד עם מסד הנתונים. נשתמש במכונה הווירטואלית הזו גם כדי להריץ מופע של Elasticsearch.

פריסת מכונה וירטואלית ב-GCE

יוצרים מכונה וירטואלית ב-GCE באותו אזור ובאותו VPC כמו אשכול AlloyDB, ומוודאים שנפח הדיסק של האתחול גדול מספיק להרצת elastic. בדוגמה הזו, אנחנו מציינים דיסק אתחול בנפח 20GB באמצעות הדגל --create-disk.

ב-Cloud Shell, מריצים את הפקודה:

export ZONE=us-central1-a
gcloud compute instances create instance-1 \
    --zone=$ZONE \
    --create-disk=auto-delete=yes,boot=yes,size=20,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

התקנת תוכנת הלקוח של PostgreSQL במכונה הווירטואלית שנפרסה

מתחברים ל-VM:

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:~$

מריצים את פקודת התוכנה בתוך ה-VM:

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.

משתמשים בערך הסיסמה (PGPASSWORD) של AlloyDB שרשמתם ובמזהה האשכול של 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=<noted password>
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 באמצעות הסימן '+' בחלק העליון.

abc505ac4d41f24e.png

בכרטיסייה החדשה של 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

סוגרים את הכרטיסייה בלחיצה על X או על ידי הפעלת הפקודה:

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:~$

בשלב הבא, מגדירים את הדגלים הנדרשים במסד הנתונים. אפשר להשתמש במסוף האינטרנט ולנהל את הדגלים במופע הראשי, או להשתמש בפקודת 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,scann.enable_preview_features=on,google_ml_integration.enable_preview_ai_functions=on,google_ml_integration.enable_ai_query_engine=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY

הפלט הצפוי במסוף

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,scann.enable_preview_features=on,google_ml_integration.enable_preview_ai_functions=on,google_ml_integration.enable_ai_query_engine=on \
   --region=$REGION \
   --cluster=$ADBCLUSTER \
   --project=$PROJECT_ID \
   --update-mode=FORCE_APPLY
Your active configuration is: [cloudshell-724]
Operation ID: operation-1775159889986-64e7f9ea9858a-b031e866-4c7c36df

כדי להפעיל את הדגלים של מסד הנתונים, צריך להפעיל מחדש את המופע. התהליך יימשך כמה דקות. אחרי שהתהליך יסתיים, הסטטוס של מופע AlloyDB יהיה 'מוכן'.

7. יצירת הטמעות וקטוריות

אחרי ייבוא הנתונים, יש לנו את הטבלאות הבאות: cymbal_products שבה מאוחסן מידע על מוצרים, cymbal_inventory שבה מתבצע מעקב אחר מלאי הפריטים בכל חנות, ו-cymbal_stores שהיא רשימה של חנויות. כדי לבצע חיפוש סמנטי במוצרים שלנו, אנחנו צריכים ליצור הטבעות וקטוריות של תיאורי המוצרים באמצעות הפונקציה initialize_embeddings. אנחנו נשתמש באינטגרציה של Vertex AI כדי לחשב נתוני וקטורים על סמך תיאורי המוצרים שלנו, ונוסיף אותם לטבלה. ניתן לקרוא מידע נוסף על הטכנולוגיה שבה נעשה שימוש במאמרי העזרה.

כדי להשתמש בשילוב, מתחברים למסד הנתונים באמצעות AlloyDB Studio או באמצעות 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 ומעלה, אבל אם במופע שלכם מופיעה גרסה ישנה יותר, כנראה שצריך לעדכן אותה. בודקים אם התחזוקה הושבתה במופע.

מתקינים את התוסף של הווקטור ויוצרים עמודה חדשה לאחסון ההטמעות ב-cymbal_products

CREATE EXTENSION IF NOT EXISTS vector;
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=>

נשתמש ביצירת הטמעה של קבוצות כדי לשפר את היעילות. במדריך אפשר לקרוא מידע נוסף על אפשרויות וטכניקות שונות ליצירת הטמעה. הפעלנו בעבר את הסימון goole_ml_integration.enable_faster_embedding_generation שמאפשר לנו ליצור הטמעות בקבוצות.

בנוסף, אנחנו רוצים שההטמעות יתעדכנו כשהערכים בעמודה משתנים, ולכן אנחנו כוללים את הארגומנט 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=>

אפשר ליצור את האינדקס במצב ידני או במצב אוטומטי. המצב 'ידני' מופעל כברירת מחדל, ואפשר ליצור אינדקס ולתחזק אותו כמו כל אינדקס אחר. אבל אם מפעילים את מצב AUTO, אפשר ליצור את האינדקס בלי שיהיה צורך לבצע תחזוקה מצדכם. במאמרי העזרה אפשר לקרוא פרטים על כל האפשרויות. במקרה שלנו, אין לנו מספיק שורות כדי ליצור את האינדקס במצב AUTO, ולכן ניצור אותו במצב MANUAL ונכלול פרמטרים של כוונון. במסמכי התיעוד מוסבר איך לשנות את הפרמטרים של האינדקס.

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 באמצעות cymbal_products_embeddings_scann ב-cymbal_products.

9. יצירת מכונה גמישה

Elasticsearch הוא סימן מסחרי של Elastic NV ואין לו קשר ל-Google LLC. אנחנו נשתמש ב-Elasticsearch לחלק של חיפוש הטקסט המלא (FTS) בחיפוש ההיברידי. אם יש לכם מכונת Elasticsearch, אתם יכולים לדלג על השלבים הבאים וליצור מפתח API אישי או מפתח API של משתמש עם הרשאת קריאה בלבד, ש-AlloyDB יכול להשתמש בו כדי לגשת לאשכול Elasticsearch שלכם. אפשרות אחרת היא התחלת הרצה של מכונת Elasticsearch וירטואלית במכונה הווירטואלית שיצרתם קודם.

מתחברים למכונה הווירטואלית באמצעות SSH ומתקינים את Docker

sudo apt-get update
sudo apt-get install -y ca-certificates curl gnupg
sudo install -m 0755 -d /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/debian/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg
sudo chmod a+r /etc/apt/keyrings/docker.gpg

echo \
  "deb [arch="$(dpkg --print-architecture)" signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/debian \
  "$(. /etc/os-release && echo "$VERSION_CODENAME")" stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin

עכשיו אפשר לשנות את פקודת Docker כדי שהמשתמש יוכל להריץ אותה

sudo usermod -aG docker $USER
newgrp docker

בטרמינל של מכונת ה-VM, מריצים את הפקודה הבאה כדי ליצור את המאגר הגמיש:

curl -fsSL https://elastic.co/start-local | sh

הפלט הצפוי (צונזר)

🎉 Congrats, Elasticsearch and Kibana are installed and running in Docker!

🌐 Open your browser at http://localhost:5601

   Username: elastic
   Password: [password_value]

🔌 Elasticsearch API endpoint: http://localhost:9200
🔑 API key: [API Key]

Learn more at https://github.com/elastic/start-local

מעתיקים את הפלט ומדביקים אותו בקובץ הבא

nano elastic-last-run.txt

‫Ctrl + O, ‏ Enter, ‏ Ctrl + X כדי לשמור ולצאת.

כברירת מחדל, קונטיינר Docker יאזין בכתובת http://localhost:9200, ויכול להיות שיהיו לו בעיות בקבלת הבקשה החיצונית מ-AlloyDB. צריך להגדיר את docker-compose.yml להאזנה ב-9200:9200

אחרי שמריצים את הסקריפט, אמורה להיווצר ספרייה חדשה בשם elastic-start-local. עוברים לספרייה הזו ועורכים את קובץ ה-Dockerfile

cd elastic-start-local/
nano docker-compose.yml

בחלק העליון של המסך מופיעות האפשרויות

  elasticsearch:
    image: docker.elastic.co/elasticsearch/elasticsearch:${ES_LOCAL_VERSION}
    container_name: ${ES_LOCAL_CONTAINER_NAME}
    volumes:
      - dev-elasticsearch:/usr/share/elasticsearch/data
    ports:
      - localhost:9200

משנים את השדה ports כך שיהיה

    ports:
      - 9200:9200

שומרים ויוצאים באמצעות Ctrl + O, ‏ Enter, ‏ Ctrl + X. עכשיו מפעילים מחדש את ה-stack.

docker compose up -d

עכשיו נאכלס את מופע Elastic עם תיאורים ושמות של מוצרים. מעתיקים את קובץ ה-CSV של המוצרים מ-Cloud Storage למכונה הווירטואלית.

gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv .

הפלט הצפוי

gcloud storage cp gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv .
Copying gs://cloud-training/gcc/gcc-tech-004/cymbal_products.csv to file://./cymbal_products.csv
  Completed files 1/1 | 1.4MiB/1.4MiB                                                                       

Average throughput: 147.9MiB/s

עכשיו יוצרים סקריפט Python לחילוץ קובץ ה-CSV ולעיצוב הנתונים בפורמט NDJSON להעלאה בכמות גדולה

nano convert.py

מדביקים את הטקסט הבא בקובץ

import csv
import json

# Configuration
input_file = 'cymbal_products.csv'
output_file = 'products.json'
index_name = 'elasticindexdemo'

def convert():
    try:
        with open(input_file, mode='r', encoding='utf-8') as f_in, \
             open(output_file, mode='w', encoding='utf-8') as f_out:
            
            reader = csv.DictReader(f_in)
            
            count = 0
            for row in reader:
                metadata = {
                    "index": {
                        "_index": index_name,
                        "_id": row['uniq_id'].strip()
                    }
                }
                
                # 2. Data/Source line
                document = {
                    "uniq_id": row['uniq_id'].strip(),
                    "product_name": row['product_name'].strip(),
                    "product_description": row['product_description'].strip()
                }
                
                # Write to file
                f_out.write(json.dumps(metadata) + '\n')
                f_out.write(json.dumps(document) + '\n')
                count += 1
                
            print(f"Success: Processed {count} products.")
            print(f"Output saved to: {output_file}")

    except Exception as e:
        print(f"An error occurred: {e}")

if __name__ == "__main__":
    convert()

שמירת הקובץ והרצתו

python3 convert.py

הפלט הצפוי

~$ python3 convert.py
Success: Processed 941 products.
Output saved to: products.json

כדי לבצע טעינה של נתונים בכמות גדולה, אנחנו צריכים לאחזר את מפתח ה-API מקובץ ההפעלה הקודם ולהשתמש בו כדי לקבל הרשאה למופע. לאחר מכן מעבירים את קובץ ה-JSON שנוצר קודם. בתרחישי ייצור, מומלץ להגדיר את האינדקס ואת סוגי הנתונים ב-Elasticsearch. מכיוון שמערך הנתונים בשיעור ה-codelab הזה קטן, אנחנו מאפשרים ל-Elasticsearch לטפל בנתונים. קודם כל, לוקחים את מפתח ה-API מהקובץ ושומרים אותו במשתנה.

AUTH_HDR=$(grep "API key" elastic-last-run.txt | sed -e "s/^.*API key:[[:space:]]*/ApiKey /g")

מריצים את פקודת ה-curl הבאה באמצעות המשתנה ששמרנו, כדי להעלות את הנתונים מקובץ ה-JSON.

curl -s -X POST "localhost:9200/elasticindexdemo/_bulk?pretty" \
  -H "Content-Type: application/x-ndjson" \
  -H "Authorization: $AUTH_HDR" \
  --data-binary "@products.json"

הפלט הצפוי

~$ curl -s -X POST "localhost:9200/elasticindexdemo/_bulk?pretty" \
  -H "Content-Type: application/x-ndjson" \
  -H "Authorization: $AUTH_HDR" \
  --data-binary "@products.json"
{
  "errors" : false,
  "took" : 1003,
  "items" : [
    {
      "index" : {
        "_index" : "elasticindexdemo",
        "_id" : "a73d5f754f225ecb9fdc64232a57bc37",
        "_version" : 1,
        "result" : "created",
        "_shards" : {
          "total" : 2,
          "successful" : 1,
          "failed" : 0
        },
        "_seq_no" : 0,
        "_primary_term" : 1,
        "status" : 201
      }
    },
...]
}
Done

לבסוף, צריך להשיג את מפתח ה-API של מופע Elasticsearch כדי שנוכל לשמור אותו לשימוש ב-AlloyDB. מריצים את הפקודה הבאה ומעתיקים את הערך של מפתח ה-API

cat elastic-last-run.txt

בעזרת מפתח ה-API, צריך ליצור סוד במנהל הסודות. ב-Cloud Shell, מריצים את הפקודה הבאה עם מפתח ה-API:

echo -n "[YOUR_API_KEY_VALUE]" | \
gcloud secrets create elasticsearch \
    --replication-policy="automatic" \
    --data-file=-

10. יצירת עטיפת נתונים חיצוניים ב-AlloyDB

משך 20:00

כדי לשלוח שאילתות לנתונים שמאוחסנים ב-Elasticsearch מ-AlloyDB, צריך ליצור Foreign Data Wrapper ‏ (FDW) עבור Elastic וטבלה חיצונית. בעבר, מפתח Elastic API אוחסן במנהל הסודות. כדי ש-AlloyDB יוכל לגשת לסוד, צריך לתת לחשבון השירות את ההרשאה הנדרשת.

ב-Cloudshell, מעניקים לחשבון השירות גישה לסוד elasticsearch

gcloud secrets add-iam-policy-binding elasticsearch \
    --member="serviceAccount:service-$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')@gcp-sa-alloydb.iam.gserviceaccount.com" \
    --role="roles/secretmanager.secretAccessor"

הפלט הצפוי

gcloud secrets add-iam-policy-binding elasticsearch \
    --member="serviceAccount:service-$(gcloud projects describe $(gcloud config get-value project) --format='value(projectNumber)')@gcp-sa-alloydb.iam.gserviceaccount.com" \
    --role="roles/secretmanager.secretAccessor"
Updated IAM policy for secret [elasticsearch].
bindings:
- members:
  - serviceAccount:service-257907437930@gcp-sa-alloydb.iam.gserviceaccount.com
  role: roles/secretmanager.secretAccessor
etag: BwZOghJiP5U=
version: 1

עוברים לאשכול AlloyDB ופותחים את AlloyDB Studio (אפשר גם להשתמש ב-psql כדי להתחבר מ-VM). מתחברים אל quickstart_db בתור המשתמש postgres.

הפעלת תוסף ה-FDW

CREATE EXTENSION external_search_fdw;

הפלט הצפוי

Statement executed successfully

כדי להגיע ל-Elasticsearch, צריך ליצור שרת נתונים חיצוני. כתובת ה-IP הפנימית של המכונה הוירטואלית מופיעה ב-Compute Engine > VM Instances (מכונות וירטואליות). כדי למצוא את הנתיב של הסוד, עוברים אל Secret Manager, בוחרים את הסוד והנתיב יופיע בחלק העליון. חשוב לוודא שכוללים את /versions/latest כדי לקבל את הגרסה העדכנית ביותר של הסוד.

CREATE SERVER elastic_demo_server
FOREIGN DATA WRAPPER external_search_fdw
OPTIONS(
    server 'http://[VM INTERNAL IP ADDRESS]:9200',
    search_provider 'elastic',
    auth_method 'ApiKey',
    secret_path '[SECRET PATH]/versions/latest'
);

בשלב הבא, מגדירים את הטבלה החיצונית. אחרי המטא-נתונים, צריך לספק את הגדרת סכימת השדות של Elasticsearch כדי להתאים לנתונים שנפרסו קודם. בטבלה המרוחקת מציינים את השם של אינדקס Elastic.

CREATE FOREIGN TABLE elasticindexdemo (
    metadata external_search_fdw_schema.OpaqueMetadata,
    uniq_id TEXT,
    product_name TEXT,
    product_description TEXT
)
SERVER elastic_demo_server
OPTIONS(
    remote_table_name 'elasticindexdemo'
);

יצירת מיפוי משתמשים לשרת

CREATE USER MAPPING FOR CURRENT_USER SERVER elastic_demo_server;

עכשיו אפשר לבדוק את הטבלה החיצונית

SELECT uniq_id, product_name
FROM elasticindexdemo
ORDER BY metadata <@> 'product_description:lamp' DESC
limit 10;

הפלט הצפוי

"uniq_id","product_name"
"59c05332f09426c23d8d005528e3c12e","CVL Mini Vintage Metal Lamp Shade: Black Metal with Punched Pattern"
"c24dd78c0d570105256e1bf1cb2fea9d","Better Homes & Gardens Tapered Drum Shade, White Box Pleat"
"7ba20db2bcfab28f88fc714d73af1eb8","4 Pack E27 Wireless Remote Control Light Lamp Bulb Holder Cap Socket Switch 30m"
"0fad1469ea9dfa80b35cfe5266b8bfe7","Star Projector Lamp, 360 Degree Star Night Light Romantic Room Rotating Cosmos Star Projuctor With USB Cable, Light Lamp Starry Moon Sky Night Projector Kid Bedroom Lamp"
"70b37e483ef3678078236d36954525ce","Lucille 10.5\""h Duck Egg Blue Empire Stitched Lamp Shade 7x10x8"
"b7a4b9151598f4cae7707cbedabe3c1b","10x12x8\"" SLIP UNO FITTER Hardback Shallow Drum Lamp Shade Textured Slate"
"5962cf47b88186eed76d14f6376882df","E27 To E14 Lampshade Lamp Light Shades Socket Reducing Ring Adapter Washer"
"7c54fdebfe0b1dd3f649741b8928a95b","iMounTEK LED Projector Lamp Kids Night Light Star Moon Projection Night Lamp 360\u00b0 Rotation Timer for Children Bedroom"
"4531201095c2653530747e215fcc1435","Home Concept Inc 11 Classics Brass Empire Lamp Shade"
"350527adb4299a015bcce74dee97805e","6 Colors LED Star Projector Lamp 360 Degree Romantic Rotating Night Cosmos Star Sky Moon Projector Kids Sleep Night Light For Children Gift Bedroom Decor"

11. שימוש בחיפוש היברידי

משך 15:00

אחרי שסיימנו את ההגדרה, אפשר להשתמש בפונקציה ai.hybrid_search() כדי לשלב בין חיפוש וקטורי לחיפוש טקסט מלא. מידע נוסף על חיפוש היברידי זמין במסמכי התיעוד. כשמשתמשים בחיפוש היברידי, כברירת מחדל, תוצאות השאילתה משתמשות באלגוריתם Reciprocal Rank Fusion כדי לדרג את התוצאות מכמה שאילתות. קודם ננסה חיפוש וקטורי וחיפוש היברידי בנפרד כדי לנתח את ההבדלים ביניהם.

השאילתה הבאה מבצעת חיפוש וקטורי כדי למצוא מוצרים שדומים לדובדבן. המערך מספק רשימה של חיפושים לביצוע. במקרה הזה אנחנו משתמשים רק בחיפוש וקטורי, אבל בהמשך נספק גם חיפוש וקטורי וגם חיפוש טקסט מלא (FTS).

SELECT id, score, cymbal_products.product_name, cymbal_products.product_description
FROM ai.hybrid_search(
  ARRAY[
      '{
        "data_type": "vector",
        "table_name": "cymbal_products",
        "key_column": "uniq_id",
        "vec_column": "product_embedding",
        "distance_operator": "public.<=>",
        "limit": 3,
        "query_vector": "ai.embedding(''text-embedding-005'', ''cherry'')::vector"
      }'::JSONB
  ]
) JOIN cymbal_products ON id = cymbal_products.uniq_id;

בפלט, עץ הדובדבן הוא התוצאה הראשונה, אבל שימו לב ששתי התוצאות הבאות הן גם עצי פרי. הסיבה לכך היא שכאשר משתמשים בחיפוש וקטורי בעמודה product_description, המערכת מוצאת התאמות סמנטיות לתנאי החיפוש.

"id","score","product_name","product_description"
"d536e9e823296a2eba198e52dd23e712","0.01639344262295082","Cherry Tree","This is a beautiful cherry tree that will produce delicious cherries. It is an deciduous tree that grows to be about 15 feet tall. The leaves are dark green in the summer and turn a beautiful red in the fall. Cherry trees are known for their beauty and their ability to provide shade and privacy. Cherry trees prefer a cool, moist climate and sandy soil. They are best suited for USDA zones 4-9."
"b70c44b1a38c0a2329fa583c9109a80f","0.016129032258064516","Peach Tree","This is a beautiful peach tree that will produce delicious peaches. It is an evergreen tree that grows to be about 20 feet tall. The leaves are dark green in the summer and turn a beautiful yellow in the fall. Peach trees are known for their beauty and their ability to provide shade and privacy. Peach trees prefer a cool, moist climate and sandy soil. They are best suited for USDA zones 2-9."
"23e41a71d63d8bbc9bdfa1d118cfddc5","0.015873015873015872","Apple Tree","This is a beautiful apple tree that will produce delicious apples. It is a deciduous tree that grows to be about 30 feet tall. The leaves are dark green in the summer and turn a beautiful red, orange, and yellow in the fall. Apple trees are known for their strength and durability. They are also a popular choice for shade trees. Apple trees prefer a cool, moist climate and loamy soil. They are best suited for USDA zones 4-8."

כדי לבצע חיפוש טקסט מלא, מריצים את השאילתה הבאה

SELECT id, score, cymbal_products.product_name, cymbal_products.product_description
FROM ai.hybrid_search(
  ARRAY[
      '{
        "limit": 3,
        "data_type": "external_search_fdw",
        "table_name": "elasticindexdemo",
        "key_column": "uniq_id",
        "query_text_input": "product_description:(cherry)"
      }'::JSONB
  ]
) JOIN cymbal_products ON id = cymbal_products.uniq_id;

שימו לב שבתוצאות, מאחר שהחיפוש בטקסט מלא מתבסס על התאמה מדויקת, מוצגים כל המוצרים שהמילה cherry מופיעה בתיאור שלהם.

"id","score","product_name","product_description"
"d536e9e823296a2eba198e52dd23e712","0.01639344262295082","Cherry Tree","This is a beautiful cherry tree that will produce delicious cherries. It is an deciduous tree that grows to be about 15 feet tall. The leaves are dark green in the summer and turn a beautiful red in the fall. Cherry trees are known for their beauty and their ability to provide shade and privacy. Cherry trees prefer a cool, moist climate and sandy soil. They are best suited for USDA zones 4-9."
"390cf08feac229e7b752709fd1f943b3","0.016129032258064516","Woven Round Placemat, Set of Twelve, Grass","...These placemats are great for special occasions and holidays, but are also perfect to accessorize your everyday place settings.|Measurements. 15-inch round diameter is the perfect size for most table sizes and shapes.|Pop Colors. Choose from 7 pop woven color placemats including: Black, Cherry, Grass, Taupe, Navy, Sun and Graphite."
"2c9aa7ac98c30abf78dd9c62a68a34e6","0.015873015873015872","48 Scented Wax Melts Wax Cubes: Jelly Belly Jelly Beans Candy Bulk Soy Wax Melts For Candle Warmer, Wax Warmers, Wax Melt Warmers In 8 Pack Set","...From These Flavors: Lemon Drop, Mixed Berry Smoothie, Sizzling Cinnamon, Crushed Pineapple, Juicy Pear, Cotton Candy, Toasted Marshmallow, French Vanilla, Watermelon, Red Apple, Very Cherry, Buttered Popcorn..."

עכשיו אפשר לשלב בין חיפוש סמנטי לבין חיפוש טקסט מלא כדי לקבל תוצאות משמעותיות יותר. נניח שאנחנו רוצים לחפש עץ שיכול לגדול לגובה שגדול יותר מגובה של בית, ושמקורו בקליפורניה. פיצלנו את השאילתה כדי להשתמש בכוונה סמנטית לעומת התאמה מילולית. החיפוש הווקטורי מטפל בחלק התיאורי: 'עץ שיכול לגדול לגובה יותר גדול מבית', כי הוא מבין את המושג של גובה וקנה מידה בלי צורך במילות מפתח מדויקות. בינתיים, החיפוש בטקסט המלא מטפל במונח 'קליפורניה' כמסנן קפדני כדי לוודא שנקבל התאמה גיאוגרפית מדויקת ולא רק משהו דומה מבחינה מושגית.

SELECT id, score, cymbal_products.product_name, cymbal_products.product_description
FROM ai.hybrid_search(
  ARRAY[
    '{
        "data_type": "vector",
        "table_name": "cymbal_products",
        "key_column": "uniq_id",
        "vec_column": "product_embedding",
        "distance_operator": "public.<=>",
        "limit": 3,
        "query_vector": "ai.embedding(''text-embedding-005'', ''tree that can grow taller than a house'')::vector"
      }'::JSONB,
      '{
        "limit": 3,
        "data_type": "external_search_fdw",
        "table_name": "elasticindexdemo",
        "key_column": "uniq_id",
        "query_text_input": "product_description:(California)"
      }'::JSONB
  ]
) JOIN cymbal_products ON id = cymbal_products.uniq_id;

התוצאות הצפויות:

"id","score","product_name","product_description"
"a589fd36a8a20fd9472d2403d6ed692a","0.00819672631147241","California Redwood","This is a beautiful redwood tree that can grow to be over 300 feet tall. It is an evergreen tree that grows in the coastal forests of California. Redwoods are known for their beauty and their strength. They are best suited for USDA zones 7-10."
"ef9432802da24041594c2cf368dfb4d2","0.008064521129029258","Madrone","This is a beautiful madrona tree that can grow to be over 80 feet tall. It is an evergreen tree that grows in the coastal forests of California. Madronas are known for their beauty and their bark. They are best suited for USDA zones 7-10."
"1360d8642bc218e4ea28e9c32b2e1721","0.007936512936504936","California Sycamore","This is a beautiful sycamore tree that can grow to be over 100 feet tall. It is an deciduous tree that grows in the valleys and foothills of California. California sycamores are known for their beauty and their shade. They are best suited for USDA zones 7-10."

12. ניקוי הסביבה

בסיום שיעור ה-Lab, משמידים את המופעים ואת האשכול של 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

13. מזל טוב

כל הכבוד, סיימתם את ה-Codelab!

מה נכלל

  • איך פורסים אשכול AlloyDB ומופע ראשי
  • איך מתחברים ל-AlloyDB ממכונה וירטואלית של Google Compute Engine
  • איך יוצרים מסד נתונים ומפעילים את AlloyDB AI
  • איך טוענים נתונים למסד הנתונים
  • איך משתמשים ב-AlloyDB Studio
  • יצירת הטמעות באמצעות Vertex AI
  • איך ליצור אינדקס וקטורי של ScaNN כדי לשפר את החיפוש הווקטורי
  • איך יוצרים Foreign Data Wrapper ‏ (FDW) ל-Elasticsearch
  • ביצוע חיפוש היברידי על ידי שילוב של חיפוש סמנטי ב-AlloyDB עם חיפוש טקסט מלא ב-Elastic.

השלבים הבאים

אפשר לעיין ב-Codelabs נוספים של AlloyDB באתר הרשמי של Codelabs.