סקירה כללית של שאילתות Spanner Graph

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

הדוגמאות במסמך הזה מבוססות על סכימת הגרף שיוצרים במאמר הגדרה של Spanner Graph וביצוע שאילתות. הסכימה הזו מודגמת בתרשים הבא:

דוגמה לסכימת Spanner Graph.
איור 1.: דוגמה לסכימה של Spanner Graph.

הרצת שאילתת Spanner Graph

אתם יכולים להשתמש במסוף Google Cloud , ב-Google Cloud CLI, בספריות לקוח, ב-REST API או ב-RPC API כדי להריץ שאילתת Spanner Graph.

מסוף Google Cloud

בשלבים הבאים מוסבר איך להריץ שאילתה במסוףGoogle Cloud . בשלבים האלה אנחנו מניחים שיש לכם מכונה בשם test-instance שמכילה מסד נתונים בשם example-db. במאמר הגדרה של Spanner Graph וביצוע שאילתות מוסבר איך ליצור מכונה עם מסד נתונים.

  1. נכנסים לדף Spanner Instances במסוף Google Cloud .

    כניסה לדף Spanner instances

  2. לוחצים על המופע שנקרא test-instance.

  3. בקטע מסדי נתונים, לוחצים על מסד הנתונים שנקרא example-db.

  4. פותחים את Spanner Studio ולוחצים על New tab (כרטיסייה חדשה) או משתמשים בכרטיסיית העריכה.

  5. מזינים שאילתה בעורך השאילתות.

  6. לוחצים על Run.

‫CLI של gcloud

כדי לשלוח שאילתות באמצעות כלי שורת הפקודה של ה-CLI של gcloud, מבצעים את הפעולות הבאות:

  1. אם הוא לא מותקן, מתקינים את ה-CLI של gcloud.

  2. ב-CLI של gcloud, מריצים את הפקודה הבאה:

    gcloud spanner databases execute-sql

למידע נוסף, אפשר לעיין במדריך למתחילים לשימוש ב-Spanner CLI.

‫API בארכיטקטורת REST

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

מידע נוסף זמין במאמרים שאילתת נתונים באמצעות API בארכיטקטורת REST ואיך מתחילים להשתמש ב-Spanner באמצעות REST.

API ל-RPC

כדי לשלוח שאילתות באמצעות RPC API, משתמשים באחת מהפקודות הבאות:

ספריות לקוח

כדי לקבל מידע נוסף על הרצת שאילתה באמצעות ספריית לקוחות של Spanner, אפשר לעיין במקורות הבאים:

מידע נוסף על ספריות הלקוח של Spanner זמין במאמר סקירה כללית על ספריות הלקוח של Spanner.

הצגה חזותית של תוצאות שאילתות ב-Spanner Graph

אפשר לראות ייצוג חזותי של תוצאות השאילתה של Spanner Graph ב-Spanner Studio במסוף Google Cloud . תצוגה חזותית של שאילתה מאפשרת לראות איך הרכיבים שמוחזרים (צמתים וקצוות) מחוברים. כך אפשר לזהות דפוסים, תלות ואנומליות שקשה לראות כשמציגים את התוצאות בטבלה. כדי להציג ויזואליזציה של שאילתה, השאילתה צריכה להחזיר צמתים מלאים בפורמט JSON. אחרת, תוכלו לראות את תוצאות השאילתה רק בפורמט טבלאי. מידע נוסף זמין במאמר שימוש בהדמיות של שאילתות גרף ב-Spanner.

מבנה השאילתות ב-Spanner Graph

שאילתת Spanner Graph מורכבת מכמה רכיבים, כמו שם גרף המאפיינים, תבניות של צמתים וקשתות, ומכמתים. אתם משתמשים ברכיבים האלה כדי ליצור שאילתה שמחפשת דפוסים ספציפיים בתרשים. כל רכיב מתואר בקטע התאמת תבניות לגרף במסמך הזה.

השאילתה באיור 2 מדגימה את המבנה הבסיסי של שאילתת Spanner Graph. השאילתה מתחילה בהגדרת גרף היעד, FinGraph, באמצעות פסוקית GRAPH. הפסקה MATCH מגדירה את התבנית לחיפוש. במקרה הזה, זהו צומת Person שמחובר לצומת Account דרך קצה Owns. הפסקה RETURN מציינת אילו מאפיינים של הצמתים התואמים יוחזרו.

דוגמה למבנה של שאילתת Spanner Graph.
איור 2.: דוגמה למבנה של שאילתת Spanner Graph.

התאמת דפוסים בגרף

התאמת תבניות לגרף מאפשרת למצוא תבניות ספציפיות בגרף. הדפוסים הבסיסיים ביותר הם דפוסי רכיבים, כמו דפוסי צמתים שתואמים לצמתים ודפוסי קצוות שתואמים לקצוות.

תבניות של צמתים

תבנית של צומת תואמת לצמתים בתרשים. הדפוס הזה מכיל סוגריים תואמים, שיכולים לכלול משתנה של דפוס גרף, ביטוי של תווית ומסנני מאפיינים.

חיפוש כל הצמתים

השאילתה הבאה מחזירה את כל הצמתים בתרשים. המשתנה n, משתנה של תבנית גרף, נקשר לצמתים התואמים. במקרה כזה, תבנית הצומת תתאים לכל הצמתים בתרשים.

GRAPH FinGraph
MATCH (n)
RETURN LABELS(n) AS label, n.id;

השאילתה הזו מחזירה את label ואת id:

תווית id
חשבון 7
חשבון 16
חשבון 20
אדם 1
אדם 2
אדם 3

חיפוש כל הצמתים עם תווית ספציפית

השאילתה הבאה תואמת לכל הצמתים בתרשים שיש להם Person תווית. השאילתה מחזירה את המאפיינים label ו-id, name של הצמתים התואמים.

GRAPH FinGraph
MATCH (p:Person)
RETURN LABELS(p) AS label, p.id, p.name;

השאילתה הזו מחזירה את המאפיינים הבאים של הצמתים התואמים:

תווית id name
אדם 1 Alex
אדם 2 Dana
אדם 3 Lee

מציאת כל הצמתים שתואמים לביטוי של תווית

אפשר ליצור ביטוי תוויות עם אופרטור לוגי אחד או יותר. לדוגמה, השאילתה הבאה תואמת לכל הצמתים בתרשים שיש להם את התווית Person או Account. משתנה תבנית הגרף n חושף את כל המאפיינים מהצמתים עם התווית Person או Account.

GRAPH FinGraph
MATCH (n:Person|Account)
RETURN LABELS(n) AS label, n.id, n.birthday, n.create_time;

בתוצאות הבאות של השאילתה הזו:

  • לכל הצמתים יש את המאפיין id.
  • לצמתים שתואמים לתווית Account יש את המאפיין create_time, אבל אין להם את המאפיין birthday. הערך של המאפיין birthday הוא NULL עבור הצמתים האלה.
  • לצמתים שתואמים לתווית Person יש את המאפיין birthday, אבל אין להם את המאפיין create_time. הערך של המאפיין create_time הוא NULL עבור הצמתים האלה.
תווית id יום הולדת create_time
חשבון 7 NULL 2020-01-10T14:22:20.222Z
חשבון 16 NULL 2020-01-28T01:55:09.206Z
חשבון 20 NULL 2020-02-18T13:44:20.655Z
אדם 1 1991-12-21T08:00:00Z NULL
אדם 2 1980-10-31T08:00:00Z NULL
אדם 3 1986-12-07T08:00:00Z NULL

חיפוש כל הצמתים שתואמים לביטוי התווית ולמסנן המאפיינים

השאילתה הזו מתאימה לכל הצמתים בתרשים שיש להם את התווית Person ושבהם המאפיין id שווה ל-1.

GRAPH FinGraph
MATCH (p:Person {id: 1})
RETURN LABELS(p) AS label, p.id, p.name, p.birthday;

אלה תוצאות השאילתה:

תווית id name יום הולדת
אדם 1 Alex 1991-12-21T08:00:00Z

אפשר להשתמש בסעיף WHERE כדי ליצור תנאי סינון מורכבים יותר על תוויות ומאפיינים.

השאילתה הבאה משתמשת בפסוקית WHERE כדי ליצור תנאי סינון מורכב יותר במאפיינים. הוא תואם לכל הצמתים בתרשים שיש להם את התווית Person, והמאפיין birthday מופיע לפני 1990-01-10.

GRAPH FinGraph
MATCH (p:Person WHERE p.birthday < '1990-01-10')
RETURN LABELS(p) AS label, p.name, p.birthday;

אלה תוצאות השאילתה:

תווית name יום הולדת
אדם Dana 1980-10-31T08:00:00Z
אדם Lee 1986-12-07T08:00:00Z

דוגמאות עיצוב לקצוות

תבנית קצה מתאימה לקצוות או לקשרים בין צמתים. תבניות קצה מוקפות בסוגריים מרובעים ([]) וכוללות סמלים כמו -, -> או <- כדי לציין כיוונים. תבנית קצה יכולה לכלול משתנה של תבנית גרף כדי לקשר לקצוות תואמים.

חיפוש כל הקצוות עם תוויות תואמות

השאילתה הזו מחזירה את כל הקצוות בתרשים עם התווית Transfers. השאילתה קושרת את משתנה תבנית הגרף e לקצוות התואמים.

GRAPH FinGraph
MATCH -[e:Transfers]->
RETURN e.Id as src_account, e.order_number

אלה תוצאות השאילתה:

src_account order_number
7 304330008004315
7 304120005529714
16 103650009791820
20 304120005529714
20 302290001255747

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

תבנית הקצה של השאילתה הזו משתמשת בביטוי תווית ובמסנן מאפיינים כדי למצוא את כל הקצוות עם התווית Transfers שתואמים לערך order_number שצוין.

GRAPH FinGraph
MATCH -[e:Transfers {order_number: "304120005529714"}]->
RETURN e.Id AS src_account, e.order_number

אלה תוצאות השאילתה:

src_account order_number
7 304120005529714
20 304120005529714

מציאת כל הקצוות באמצעות תבנית קצה בכל כיוון

אפשר להשתמש בדפוס הקצה any direction (-[]-) בשאילתה כדי להתאים לקצוות בכל כיוון. השאילתה הבאה מוצאת את כל ההעברות עם חשבון חסום.

GRAPH FinGraph
MATCH (account:Account)-[transfer:Transfers]-(:Account {is_blocked:true})
RETURN transfer.order_number, transfer.amount;

אלה תוצאות השאילתה:

order_number amount
304330008004315 300
304120005529714 100
103650009791820 300
302290001255747 200

דפוסי נתיבים

תבנית נתיב מורכבת מתבניות של צמתים וקשתות לסירוגין.

חיפוש כל הנתיבים מצומת ספציפית באמצעות תבנית נתיב

השאילתה הבאה מוצאת את כל ההעברות לחשבון שהתחילו מחשבון בבעלות Person עם id ששווה ל-2.

כל תוצאה תואמת מייצגת נתיב מ-Person {id: 2} דרך Account מחובר באמצעות קצה Owns, אל Account אחר באמצעות קצה Transfers.

GRAPH FinGraph
MATCH
  (p:Person {id: 2})-[:Owns]->(account:Account)-[t:Transfers]->
  (to_account:Account)
RETURN
  p.id AS sender_id, account.id AS from_id, to_account.id AS to_id;

אלה תוצאות השאילתה:

sender_id from_id to_id
2 20 7
2 20 16

דפוסי נתיבים כמותיים

תבנית כמותית חוזרת על תבנית בטווח שצוין.

התאמה לדוגמת עיצוב של קצה עם ערך כמותי

כדי למצוא נתיבים באורך משתנה, אפשר להחיל כמותן על תבנית קצה. השאילתה הבאה היא דוגמה לכך. היא מוצאת חשבונות יעד שנמצאים במרחק של העברה אחת עד שלוש מהמקור Account עם id של 7.

השאילתה מחילה את הכמת {1, 3} על תבנית הקצה -[e:Transfers]->. ההוראה הזו בשאילתה היא להתאים נתיבים שבהם חוזר דפוס הקצה Transfers פעם אחת, פעמיים או שלוש. הסעיף WHERE משמש להחרגת חשבון המקור מהתוצאות. הפונקציה ARRAY_LENGTH משמשת לגישה אל group variable e. מידע נוסף זמין במאמר בנושא משתנה של קבוצת גישה.

GRAPH FinGraph
MATCH (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account)
WHERE src != dst
RETURN src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length, dst.id AS dst_account_id;

אלה תוצאות השאילתה:

src_account_id path_length dst_account_id
7 1 16
7 1 16
7 3 16
7 3 16
7 2 20
7 2 20

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

התאמה של תבנית נתיב כמותית

השאילתה הבאה מוצאת נתיבים בין צמתי Account עם קשתות Transfers אחת או שתיים דרך חשבונות ביניים חסומים.

תבנית הנתיב שבסוגריים עוברת כימות, והסעיף WHERE שלה מציין תנאים לתבנית החוזרת.

GRAPH FinGraph
MATCH
  (src:Account)
  ((a:Account)-[:Transfers]->(b:Account {is_blocked:true}) WHERE a != b){1,2}
    -[:Transfers]->(dst:Account)
RETURN src.id AS src_account_id, dst.id AS dst_account_id;

אלה תוצאות השאילתה:

src_account_id dst_account_id
7 20
7 20
20 20

משתני קבוצה

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

אפשר לגשת למשתנה קבוצה כמערך. רכיבי הגרף נשמרים בסדר שבו הם מופיעים לאורך הנתיבים התואמים. אפשר לצבור משתנה קיבוץ באמצעות צבירה אופקית.

משתנה של קבוצת גישה

בדוגמה הבאה, הגישה למשתנה e מתבצעת באופן הבא:

  • משתנה של דפוס גרף שקשור לקצה יחיד בסעיף WHERE e.amount > 100 כשהוא נמצא בתוך הדפוס הכמותי.
  • משתנה קבוצה שקשור למערך של רכיבי קצה ב-ARRAY_LENGTH(e) בהצהרה RETURN כשהוא מחוץ לתבנית הכמותית.
  • משתנה קבוצה שקשור למערך של רכיבי קצה, שמצטבר על ידי SUM(e.amount) מחוץ לתבנית הכמותית. זו דוגמה לצבירה אופקית.
GRAPH FinGraph
MATCH
  (src:Account {id: 7})-[e:Transfers WHERE e.amount > 100]->{0,2}
  (dst:Account)
WHERE src.id != dst.id
LET total_amount = SUM(e.amount)
RETURN
  src.id AS src_account_id, ARRAY_LENGTH(e) AS path_length,
  total_amount, dst.id AS dst_account_id;

אלה תוצאות השאילתה:

src_account_id path_length total_amount dst_account_id
7 1 300 16
7 2 600 20

קידומות לחיפוש נתיבים

כדי להגביל את הנתיבים התואמים בתוך קבוצות שחולקות צומתי מקור ויעד, אפשר להשתמש בקידומת החיפוש של הנתיב ANY,‏ ANY SHORTEST או ANY CHEAPEST. אפשר להוסיף את הקידומות האלה רק לפני תבנית של נתיב שלם, ואי אפשר להוסיף אותן בתוך סוגריים.

התאמה באמצעות ANY

השאילתה הבאה מוצאת את כל החשבונות הייחודיים שאפשר להגיע אליהם, שנמצאים במרחק של אחד או שני Transfers צעדים מצומת Account נתונה.

הקידומת ANY של חיפוש הנתיב מבטיחה שהשאילתה תחזיר רק נתיב אחד בין צמד ייחודי של צמתי src ו-dst Account. בדוגמה הבאה, למרות שאפשר להגיע לצומת Account עם {id: 16} בשני נתיבים שונים מצומת המקור Account, השאילתה מחזירה רק נתיב אחד.

GRAPH FinGraph
MATCH ANY (src:Account {id: 7})-[e:Transfers]->{1,2}(dst:Account)
LET ids_in_path = ARRAY_CONCAT(ARRAY_AGG(e.Id), [dst.Id])
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ids_in_path;

אלה תוצאות השאילתה:

src_account_id dst_account_id ids_in_path
7 16 ‫7,16
7 20 ‫7,16,20

התאמה באמצעות ANY SHORTEST

הקידומת ANY SHORTEST של חיפוש נתיב מחזירה נתיב יחיד לכל זוג של צמתי מקור ויעד, שנבחר מתוך הנתיבים עם המספר המינימלי של קשתות.

לדוגמה, השאילתה הבאה מוצאת את אחת הדרכים הקצרות ביותר בין צומת Account עם id 7 לבין צומת Account עם id של 20. השאילתה מתייחסת לנתיבים עם קצה אחד עד שלושה Transfers.

GRAPH FinGraph
MATCH ANY SHORTEST (src:Account {id: 7})-[e:Transfers]->{1, 3}(dst:Account {id: 20})
RETURN src.id AS src_account_id, dst.id AS dst_account_id, ARRAY_LENGTH(e) AS path_length;

אלה תוצאות השאילתה:

src_account_id dst_account_id path_length
7 20 2

התאמה באמצעות ANY CHEAPEST

קידומת החיפוש של הנתיב ANY CHEAPEST מוודאת שכל שאילתה תחזיר רק נתיב אחד עם עלות החישוב הכוללת המינימלית, לכל צמד של חשבונות מקור ויעד.

השאילתה הבאה מוצאת נתיב עם עלות כוללת מינימלית של מחשוב בין צמתי Account. העלות הזו מבוססת על סכום המאפיין amount של קצוות Transfers. החיפוש מתבצע בשבילים עם קצה אחד עד שלושה Transfers קצוות.

GRAPH FinGraph
MATCH ANY CHEAPEST (src:Account)-[e:Transfers COST e.amount]->{1,3}(dst:Account)
LET total_cost = sum(e.amount)
RETURN src.id AS src_account_id, dst.id AS dst_account_id, total_cost

אלה תוצאות השאילתה:

src_account_id dst_account_id total_cost
7 7 900
7 16 100
7 20 400
16 7 800
16 16 500
16 20 300
20 7 500
20 16 200
20 20 500

דפוסים בגרף

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

התאמה באמצעות תבנית גרף

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

תבניות הנתיבים הבאות יוצרות את תבנית הגרף:

  • התבנית הראשונה מוצאת נתיבים שבהם ההעברה מתבצעת מחשבון אחד לחשבון חסום באמצעות חשבון ביניים.
  • התבנית השנייה מוצאת נתיבים מחשבון לאדם שהוא הבעלים שלו.

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

GRAPH FinGraph
MATCH
  (src:Account)-[t1:Transfers]->(interm:Account)-[t2:Transfers]->(dst:Account),
  (interm)<-[:Owns]-(p:Person)
WHERE dst.is_blocked = TRUE AND t1.amount > 200 AND t2.amount > 200
RETURN
  src.id AS src_account_id, dst.id AS dst_account_id,
  interm.id AS interm_account_id, p.id AS owner_id;

אלה תוצאות השאילתה:

src_account_id dst_account_id interm_account_id owner_id
20 16 7 1

משפטי שאילתה לינאריים

אפשר לשרשר כמה הצהרות גרף כדי ליצור הצהרת שאילתה לינארית. ההצהרות מבוצעות באותו סדר שבו הן מופיעות בשאילתה.

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

  • הפלט של ההצהרה האחרונה הוא התוצאה הסופית.

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

GRAPH FinGraph
MATCH (src_account:Account)-[transfer:Transfers]->(dst_account:Account {is_blocked:true})
ORDER BY transfer.amount DESC
LIMIT 1
MATCH (src_account:Account)<-[owns:Owns]-(owner:Person)
RETURN src_account.id AS account_id, owner.name AS owner_name;

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

דף חשבון תוצאת ביניים (בקיצור)
MATCH
  (src_account:Account)
    -[transfer:Transfers]->
  (dst_account:Account {is_blocked:true})
src_account העברה dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}

ORDER BY transfer.amount DESC
src_account העברה dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}
{id: 20} {amount: 200.0} {id: 16, is_blocked: true}
{id: 7} {amount: 100.0} {id: 16, is_blocked: true}

LIMIT 1
src_account העברה dst_account
{id: 7} {amount: 300.0} {id: 16, is_blocked: true}

MATCH
  (src_account:Account)
    <-[owns:Owns]-
  (owner:Person)
src_account העברה dst_account owns בעלים
{id: 7} {amount: 300.0} {id: 16, is_blocked: true} {person_id: 1, account_id: 7} {id: 1, name: Alex}
RETURN
  src_account.id AS account_id,
  owner.name AS owner_name
        
account_id owner_name
7 Alex

אלה תוצאות השאילתה:

account_id owner_name
7 Alex

פקודת חזרה

המשפט RETURN מציין מה להחזיר מהדפוסים התואמים. היא יכולה לגשת למשתני תבנית גרף ולכלול ביטויים וסעיפים אחרים, כמו ORDER BY ו-GROUP BY.

‫Spanner Graph לא תומך בהחזרת רכיבי גרף כתוצאות של שאילתה. כדי להחזיר את כל רכיב הגרף, משתמשים בפונקציה TO_JSON או בפונקציה SAFE_TO_JSON. מבין שתי הפונקציות האלה, מומלץ להשתמש בפונקציה SAFE_TO_JSON.

החזרת רכיבי גרף כ-JSON

GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Returning a graph element in the final results is NOT allowed. Instead, use
-- the TO_JSON function or explicitly return the graph element's properties.
RETURN TO_JSON(n) AS n;
GRAPH FinGraph
MATCH (n:Account {id: 7})
-- Certain fields in the graph elements, such as TOKENLIST, can't be returned
-- in the TO_JSON function. In those cases, use the SAFE_TO_JSON function instead.
RETURN SAFE_TO_JSON(n) AS n;

אלה תוצאות השאילתה:

n
{"identifier":"mUZpbkdyYXBoLkFjY291bnQAeJEO","kind":"node","labels":["Account"],"properties":{"create_time":"2020-01-10T14:22:20.222Z","id":7,"is_blocked":false,"nick_name":"Vacation Fund"}}

כתיבת שאילתות גדולות יותר באמצעות מילת המפתח NEXT

אפשר לשרשר כמה הצהרות של שאילתות לינאריות של גרפים באמצעות מילת המפתח NEXT. ההצהרה הראשונה מקבלת קלט ריק, והפלט של כל הצהרה עוקבת הופך לקלט של ההצהרה הבאה.

בדוגמה הבאה מוצאים את הבעלים של החשבון עם הכי הרבה העברות נכנסות על ידי שרשור של כמה הצהרות לינאריות של גרף. אפשר להשתמש באותו משתנה, למשל account, כדי להתייחס לאותו רכיב בתרשים בכמה הצהרות לינאריות.

GRAPH FinGraph
MATCH (:Account)-[:Transfers]->(account:Account)
RETURN account, COUNT(*) AS num_incoming_transfers
GROUP BY account
ORDER BY num_incoming_transfers DESC
LIMIT 1

NEXT

MATCH (account:Account)<-[:Owns]-(owner:Person)
RETURN account.id AS account_id, owner.name AS owner_name, num_incoming_transfers;

אלה תוצאות השאילתה:

account_id owner_name num_incoming_transfers
16 Lee 3

פונקציות וביטויים

אפשר להשתמש בכל הפונקציות של GoogleSQL (פונקציות מצטברות ופונקציות סקלריות), באופרטורים ובביטויים מותנים בשאילתות של Spanner Graph. ‫Spanner Graph תומך גם בפונקציות ובאופרטורים ספציפיים לגרפים.

פונקציות ואופרטורים מובנים

הפונקציות והאופרטורים הבאים נמצאים בשימוש ב-GQL:

  • PROPERTY_EXISTS(n, birthday): מחזירה את הערך True אם למשתנה n יש את המאפיין birthday, אחרת מחזירה את הערך False.
  • LABELS(n): מחזירה את התוויות של n כפי שהוגדרו בסכימת הגרף.
  • PROPERTY_NAMES(n): מחזירה את שמות המאפיינים של n.
  • TO_JSON(n): מחזירה n בפורמט JSON. מידע נוסף זמין במאמר בנושא הפונקציה TO_JSON.

הפונקציה PROPERTY_EXISTS, הפונקציה LABELS והפונקציה TO_JSON, וגם פונקציות מובנות אחרות כמו ARRAY_AGG ו-CONCAT.

GRAPH FinGraph
MATCH (person:Person)-[:Owns]->(account:Account)
RETURN person, ARRAY_AGG(account.nick_name) AS accounts
GROUP BY person

NEXT

RETURN
  LABELS(person) AS labels,
  TO_JSON(person) AS person,
  accounts,
  CONCAT(person.city, ", ", person.country) AS location,
  PROPERTY_EXISTS(person, is_blocked) AS is_blocked_property_exists,
  PROPERTY_EXISTS(person, name) AS name_property_exists
LIMIT 1;

אלה תוצאות השאילתה:

is_blocked_property_exists name_property_exists labels חשבונות location אדם
false true Person ["Vacation Fund"] Adelaide, Australia {"identifier":"mUZpbkdyYXBoLlBlcnNvbgB4kQI=","kind":"node","labels":["Person"],"properties":{"birthday":"1991-12-21T08:00:00Z","city":"Adelaide","country":"Australia","id":1,"name":"Alex"}}

שאילתות משנה

שאילתת משנה היא שאילתה שמוטמעת בתוך שאילתה אחרת. הכללים הבאים חלים על שאילתות משנה של Spanner Graph:

  • שאילתת משנה מוקפת בזוג סוגריים מסולסלים {}.
  • יכול להיות שתת-שאילתה תתחיל עם פסקה מובילה של GRAPH כדי לציין את הגרף שבתחום. הגרף שצוין לא צריך להיות זהה לגרף שבו נעשה שימוש בשאילתה החיצונית.
  • אם משמיטים את פסוקית GRAPH בשאילתת המשנה, קורה הדבר הבא:
    • הגרף שבתחום מוסק מההקשר הקרוב ביותר של השאילתה החיצונית.
    • שאילתת המשנה חייבת להתחיל בהצהרה של התאמת תבנית גרף עם MATCH.
  • אי אפשר להצהיר שוב על משתנה של תבנית גרף שהוצהר מחוץ להיקף של שאילתת המשנה, אבל אפשר להתייחס אליו בביטויים או בפונקציות בתוך שאילתת המשנה.

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

השאילתה הבאה מדגימה את השימוש בשאילתת המשנה VALUE. שאילתת המשנה מוקפת בסוגריים מסולסלים {} עם הקידומת של מילת המפתח VALUE. השאילתה מחזירה את המספר הכולל של העברות שהתחילו מחשבון.

GRAPH FinGraph
MATCH (p:Person)-[:Owns]->(account:Account)
RETURN p.name, account.id AS account_id, VALUE {
  MATCH (a:Account)-[transfer:Transfers]->(:Account)
  WHERE a = account
  RETURN COUNT(transfer) AS num_transfers
} AS num_transfers;

אלה תוצאות השאילתה:

name account_id num_transfers
Alex 7 2
Dana 20 2
Lee 16 1

רשימה של ביטויי שאילתות משנה נתמכים מופיעה במאמר בנושא שאילתות משנה ב-Spanner Graph.

שימוש בשאילתת משנה כדי למצוא חשבונות שבבעלות כל אדם

השאילתה הבאה משתמשת בהצהרה CALL עם שאילתת משנה מוטמעת. ההצהרה MATCH (p:Person) יוצרת טבלה עם עמודה אחת בשם p. כל שורה בטבלה הזו מכילה צומת Person. ההצהרה CALL (p) מפעילה את שאילתת המשנה המצורפת לכל שורה בטבלת העבודה הזו. שאילתת המשנה מוצאת חשבונות שנמצאים בבעלות של כל אדם שתואם p. כמה חשבונות של אותו אדם ממוינים לפי מזהה החשבון.

בדוגמה מוצהר על משתנה הצומת p בהיקף החיצוני מהסעיף MATCH (p:Person). המשתנה הזה מוזכר בהצהרה CALL (p). ההצהרה הזו מאפשרת להצהיר מחדש על משתנה הצומת או להצהיר עליו כמה פעמים בתבנית הנתיב של שאילתת המשנה. כך מוודאים שמשתני הצומת p node הפנימי והחיצוני קשורים לאותו צומת Person בתרשים. אם המשפט CALL לא מגדיר את משתנה הצומת p, שאילתת המשנה מתייחסת למשתנה p שהוגדר מחדש כמשתנה חדש. המשתנה החדש הזה לא תלוי במשתנה בהיקף החיצוני, והשאילתה המשנית לא מצהירה עליו כמה פעמים כי היא מחזירה תוצאות שונות. מידע נוסף זמין בCALL.

GRAPH FinGraph
MATCH (p:Person)
CALL (p) {
  MATCH (p)-[:Owns]->(a:Account)
  RETURN a.Id AS account_Id
  ORDER BY account_Id
}
RETURN p.name AS person_name, account_Id
ORDER BY person_name, account_Id;

תוצאה

person_name account_Id
Alex 7
Dana 20
Lee 16

פרמטרים של שאילתה

אפשר להריץ שאילתות ב-Spanner Graph עם פרמטרים. מידע נוסף זמין במאמרים בנושא תחביר ושאילתת נתונים עם פרמטרים בספריות הלקוח של Spanner.

השאילתה הבאה ממחישה את השימוש בפרמטרים של שאילתה.

GRAPH FinGraph
MATCH (person:Person {id: @id})
RETURN person.name;

הרצת שאילתות על גרפים וטבלאות ביחד

אתם יכולים להשתמש בשאילתות גרף בשילוב עם SQL כדי לגשת למידע מהגרפים והטבלאות שלכם יחד בהצהרה אחת.

האופרטור GRAPH_TABLE מקבל שאילתת גרף לינארי ומחזיר את התוצאה שלה בפורמט טבלאי שאפשר לשלב בשאילתת SQL. היכולת הזו מאפשרת להעשיר תוצאות של שאילתות גרף בתוכן שאינו גרף, ולהיפך.

לדוגמה, אפשר ליצור טבלה CreditReports ולהוסיף כמה דוחות אשראי, כמו בדוגמה הבאה:

CREATE TABLE CreditReports (
  person_id     INT64 NOT NULL,
  create_time   TIMESTAMP NOT NULL,
  score         INT64 NOT NULL,
) PRIMARY KEY (person_id, create_time);
INSERT INTO CreditReports (person_id, create_time, score)
VALUES
  (1,"2020-01-10 06:22:20.222", 700),
  (2,"2020-02-10 06:22:20.222", 800),
  (3,"2020-03-10 06:22:20.222", 750);

לאחר מכן, תוכלו לזהות אנשים ספציפיים באמצעות התאמת תבניות גרף ב-GRAPH_TABLE ולצרף את תוצאות שאילתת הגרף לטבלה CreditReports כדי לאחזר את דירוג האשראי.

SELECT
  gt.person.id,
  credit.score AS latest_credit_score
FROM GRAPH_TABLE(
  FinGraph
  MATCH (person:Person)-[:Owns]->(:Account)-[:Transfers]->(account:Account {is_blocked:true})
  RETURN DISTINCT person
) AS gt
JOIN CreditReports AS credit
  ON gt.person.id = credit.person_id
ORDER BY credit.create_time;

אלה תוצאות השאילתה:

person_id latest_credit_score
1 700
2 800

המאמרים הבאים

שיטות מומלצות להתאמת שאילתות