סקירה כללית של שאילתות 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 ולוחצים על כרטיסייה חדשה או משתמשים בכרטיסיית העריכה.

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

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

‫CLI של gcloud

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

לדוגמה, השאילתה הבאה מוצאת את אחד הנתיבים הקצרים ביותר בין צומת 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 edges.

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

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

שיטות מומלצות לשיפור שאילתות