שליחת שאילתות לנתוני Avro

באמצעות GoogleSQL ל-Bigtable אתם יכולים לשלוח שאילתות, לסנן ולהקרין שדות ספציפיים מרשומות Apache Avro שעברו סריאליזציה ונשמרו בטבלאות Bigtable. אם תפנו לחבילת סכימות של Avro בשאילתות SQL, תוכלו להמיר עמודות של בייטים לרשומות מובְנות של Avro ולחלץ שדות בתצוגת עץ.

לפני ששולחים שאילתות לשדות Avro, צריך להעלות את הסכימות של Avro בחבילת סכימות, כמו שמתואר במאמר יצירה וניהול של סכימות Avro. בסקירה הכללית של GoogleSQL ל-Bigtable מוסבר איך שאילתות GoogleSQL ממפות לסכימות של טבלאות Bigtable ואיך להפנות לעמודות בהצהרות SQL.

כדי לשלוח שאילתות על נתוני Avro באמצעות GoogleSQL ב-Java, משתמשים ב-method‏ executeQuery בספריית הלקוח של Cloud Bigtable. דוגמאות להרצת שאילתות SQL באמצעות ספריות לקוח מופיעות במאמר ספריות לקוח.

מיפויים של סוגי נתונים ב-Avro

כשממירים BYTES שעבר סריאליזציה לרשומת Avro, ‏GoogleSQL ל-Bigtable ממפה את סוגי הסכימות של Avro לסוגים שאפשר לגשת אליהם באמצעות SQL, באופן הבא:

סוג Avro ייצוג ב-GoogleSQL תיאור
int, long INT64 מספרים שלמים עם סימן של 32 ביט ו-64 ביט ממופים למספרים שלמים של 64 ביט.
float FLOAT32 ערך של נקודה צפה (floating-point) עם דיוק יחיד
double FLOAT64 ערך נקודה צפה (floating-point) עם דיוק כפול
boolean BOOL ערך בוליאני (TRUE או FALSE)
string STRING רצף תווים ב-Unicode
bytes BYTES רצף של בייטים גולמיים
record אובייקט ההודעה אפשר לגשת לשדות מקוננים באמצעות סימון הנקודות (לדוגמה, record.field).
enum ENUM קבוצת סמלים ממוספרת
array ARRAY שדה חוזר. ב-Bigtable אין תמיכה במערכים בתוך מערכים.
map<T> רשומות חוזרות של מפתח/ערך למפות Avro יש STRING מפתחות. Bigtable תומך במפות עם ערכים שיכולים להיות ריקים, כמו {"type": "map", "values": ["null", "string"]}. אפשר להמיר את המפות ל-ARRAY<STRUCT<key STRING, value T>> באמצעות הפונקציה ARRAY_TRANSFORM.
union שדה שיכול להיות ריק ‫Bigtable ממפה איחוד עם ערך null וסוג אחד שאינו null לשדה רגיל שיכול להכיל ערך null.
fixed ב-Bigtable אין תמיכה בסוג fixed. רצף בייטים באורך קבוע.

נתונים לדוגמה

בדוגמאות שבדף הזה נעשה שימוש בחבילת סכימות של Avro עם המזהה my_avro. החבילה הזו מכילה את סכימת הרשומה הבאה של Transaction במרחב השמות com.example.billing:

{
  "type": "record",
  "namespace": "com.example.billing",
  "name": "Transaction",
  "fields": [
    {"name": "product_name", "type": "string"},
    {"name": "product_category", "type": "string"},
    {"name": "configs", "type": {"type": "map", "values": "string"}}
  ]
}

בטבלה של Bigtable בשם table מאוחסנות רשומות Avro שעברו סריאליזציה בקבוצת העמודות cf ובמגדיר העמודה product (cf['product']):

מפתח שורה עמודה cf['product'] (מאוחסנת כ-BYTES בסדרה, מוצגת כ-JSON כדי שיהיה קל לקרוא אותה)
row1 {"product_name": "Chips", "product_category": "yummy food", "configs": {"size": "large", "flavor": "BBQ"}}
row2 {"product_name": "Apple", "product_category": "yummy food", "configs": {}}
row3 {"product_name": "Book", "product_category": "reading", "configs": {"author": "Jane Doe"}}

שאילתות לדוגמה

אחרי שמעלים את חבילת הסכימות של Avro, אפשר להשתמש באופרטור CAST ב-GoogleSQL ל-Bigtable כדי לפרש ערכי BYTES כרשומת Avro.

המרת עמודה והקרנת שדה

כדי להמיר ערך BYTES לרשומת Avro, צריך לציין את שם הרשומה המלא בפורמט הבא:

SCHEMA_BUNDLE_ID.FULLY_QUALIFIED_RECORD_NAME

מחליפים את מה שכתוב בשדות הבאים:

  • ‫SCHEMA_BUNDLE_ID: המזהה של חבילת הסכימה
  • ‫FULLY_QUALIFIED_RECORD_NAME: השם המלא של רשומת Avro, כולל מרחב השמות שמוגדר בסכימת Avro – לדוגמה, com.example.billing.Transaction

אם חבילת הסכימה או שם הרשומה שצוינו לא קיימים, השאילתה תיכשל עם סטטוס INVALID_ARGUMENT והודעת השגיאה type not found. אם הסכימה שסופקה לא יכולה לנתח את הבייטים של התא, השאילתה נכשלת עם סטטוס FAILED_PRECONDITION או INVALID_ARGUMENT.

השאילתה הבאה ממירה את העמודה cf['product'] לרשומה com.example.billing.Transaction בחבילת הסכימה my_avro, ומציגה את השדה product_name:

SELECT
  CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name
FROM
  table;

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

product_name (STRING)
צ'יפים
Apple
ספר

סינון לפי שדות Avro

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

השאילתה הבאה מסננת שורות שבהן השדה product_category שווה ל-"yummy food":

SELECT
  CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name
FROM
  table
WHERE
  CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_category = "yummy food";

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

product_name (STRING)
צ'יפים
Apple

שדות של מפות גישה

אפשר להשתמש בפונקציה ARRAY_TRANSFORM כדי להקרין צמדי מפתח/ערך משדה Avro map כמערך של רכיבי STRUCT.

השאילתה הבאה מקרינה את product_name ומשנה את שדה המפה configs למערך של רכיבי STRUCT<key STRING, value STRING>:

SELECT
  CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name,
  ARRAY_TRANSFORM(
    CAST(cf['product'] AS my_avro.com.example.billing.Transaction).configs,
    e -> STRUCT(e.key, e.value)
  ) AS map_array
FROM
  table;

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

product_name (STRING) map_array (ARRAY<STRUCT<key STRING, value STRING>>)
צ'יפים [{"key": "size", "value": "large"}, {"key": "flavor", "value": "BBQ"}]
Apple []
ספר [{"key": "author", "value": "Jane Doe"}]

שימוש בתצוגות

אפשר להפנות לחבילות סכימות של Avro בתצוגות מהותיות רציפות ובתצוגות לוגיות.

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

הפקודה הבאה יוצרת תצוגה מהותית רציפה שצוברת את מספר העסקאות לפי product_name:

gcloud bigtable materialized-views create MATERIALIZED_VIEW_ID \
    --instance=INSTANCE_ID \
    --query="SELECT CAST(cf['product'] AS my_avro.com.example.billing.Transaction).product_name AS product, COUNT(*) AS transaction_count FROM table GROUP BY product;"

מחליפים את מה שכתוב בשדות הבאים:

  • ‫MATERIALIZED_VIEW_ID: המזהה של התצוגה המהותית הרציפה שמפנה לחבילת הסכימה
  • ‫INSTANCE_ID: המזהה של מכונת Bigtable

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