Node.js hello world

דוגמת הקוד הזו היא אפליקציית Hello World שפועלת ב-Node.js. בדוגמה הזו מוסבר איך לבצע את הפעולות הבאות:

  • מגדירים אימות
  • מתחברים למכונה של Bigtable.
  • ליצור טבלה חדשה.
  • כתיבת נתונים בטבלה.
  • קוראים את הנתונים בחזרה.
  • מוחקים את הטבלה.

מגדירים אימות

כדי להשתמש בדוגמאות של Node.js שבדף הזה בסביבת פיתוח מקומית, מתקינים ומפעילים את ה-CLI של gcloud, ואז מגדירים את Application Default Credentials באמצעות פרטי הכניסה של המשתמש.

  1. התקינו את ה-CLI של Google Cloud.

  2. הגדירו שה-CLI של gcloud ישתמש בזהות המאוחדת שלכם.

    איך נכנסים ל-CLI של gcloud באמצעות הזהות המאוחדת?

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

    gcloud auth application-default login

    אם מוחזרת שגיאת אימות, צריך לוודא ש נכנסתם ל-CLI של gcloud באמצעות הזהות המאוחדת שלכם.

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

הרצת הדוגמה

בדוגמת הקוד הזו נעשה שימוש בחבילת Bigtable של ספריית הלקוח של Google Cloud ל-Node.js כדי לתקשר עם Bigtable.

כדי להריץ את תוכנית הדוגמה הזו, פועלים לפי ההוראות לדוגמה ב-GitHub.

שימוש בספריית הלקוח של Cloud עם Bigtable

אפליקציית הדוגמה מתחברת ל-Bigtable ומדגימה כמה פעולות פשוטות.

הוספת דרישה לספריית הלקוח

הדוגמה דורשת את המודול @google-cloud/bigtable, שמספק את המחלקה Bigtable.

const {Bigtable} = require('@google-cloud/bigtable');

התחברות ל-Bigtable

כדי להתחבר ל-Bigtable, יוצרים אובייקט Bigtable חדש. לאחר מכן, מפעילים את ה-method‏ instance() כדי לקבל אובייקט Instance שמייצג את המכונה של Bigtable.

const bigtableClient = new Bigtable();
const instance = bigtableClient.instance(INSTANCE_ID);
const table = instance.table(TABLE_ID);

יצירת טבלה

קוראים לשיטה table() של המופע כדי לקבל אובייקט Table שמייצג את הטבלה של ברכות hello world. אם הטבלה לא קיימת, קוראים ל-method‏ create() של הטבלה כדי ליצור טבלה עם קבוצת עמודות אחת ששומרת גרסה אחת של כל ערך.

const {BigtableTableAdminClient} = require('@google-cloud/bigtable').v2;
const adminClient = new BigtableTableAdminClient();
const projectId = await adminClient.getProjectId();

let tableExists = true;
try {
  await adminClient.getTable({
    name: `projects/${projectId}/instances/${INSTANCE_ID}/tables/${TABLE_ID}`,
  });
} catch (e) {
  if (e.code === 5) {
    tableExists = false;
  }
}
if (!tableExists) {
  console.log(`Creating table ${TABLE_ID}`);
  const {BigtableTableAdminClient} = require('@google-cloud/bigtable').v2;
  const adminClient = new BigtableTableAdminClient();
  const projectId = await adminClient.getProjectId();
  await adminClient.createTable({
    parent: `projects/${projectId}/instances/${INSTANCE_ID}`,
    tableId: TABLE_ID,
    table: {
      columnFamilies: {
        [COLUMN_FAMILY_ID]: {
          gcRule: {
            maxNumVersions: 1,
          },
        },
      },
    },
  });
}

כתיבת שורות לטבלה

משתמשים במערך של מחרוזות ברכה כדי ליצור כמה שורות חדשות בטבלה: קוראים ל-method‏ map() של המערך כדי ליצור מערך חדש של אובייקטים שמייצגים שורות, ואז קוראים ל-method‏ insert() של הטבלה כדי להוסיף את השורות לטבלה.

console.log('Write some greetings to the table');
const greetings = ['Hello World!', 'Hello Bigtable!', 'Hello Node!'];
const rowsToInsert = greetings.map((greeting, index) => ({
  // Note: This example uses sequential numeric IDs for simplicity, but this
  // pattern can result in poor performance in a production application.
  // Rows are stored in sorted order by key, so sequential keys can result
  // in poor distribution of operations across nodes.
  //
  // For more information about how to design an effective schema for Cloud
  // Bigtable, see the documentation:
  // https://cloud.google.com/bigtable/docs/schema-design
  key: `greeting${index}`,
  data: {
    [COLUMN_FAMILY_ID]: {
      [COLUMN_QUALIFIER]: {
        // Setting the timestamp allows the client to perform retries. If
        // server-side time is used, retries may cause multiple cells to
        // be generated.
        timestamp: new Date(),
        value: greeting,
      },
    },
  },
}));
await table.insert(rowsToInsert);

יצירת מסנן

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

const filter = [
  {
    column: {
      cellLimit: 1, // Only retrieve the most recent version of the cell.
    },
  },
];

קריאת שורה לפי מפתח השורה

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

console.log('Reading a single row by row key');
const [singleRow] = await table.row('greeting0').get({filter});
console.log(`\tRead: ${getRowGreeting(singleRow)}`);

סריקת כל השורות בטבלה

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

console.log('Reading the entire table');
// Note: For improved performance in production applications, call
// `Table#readStream` to get a stream of rows. See the API documentation:
// https://cloud.google.com/nodejs/docs/reference/bigtable/latest/Table#createReadStream
const [allRows] = await table.getRows({filter});
for (const row of allRows) {
  console.log(`\tRead: ${getRowGreeting(row)}`);
}

מחיקת טבלה

מוחקים את הטבלה באמצעות השיטה delete() של הטבלה.

console.log('Delete the table');
const request = {
  name: `projects/${projectId}/instances/${INSTANCE_ID}/tables/${TABLE_ID}`,
};
await adminClient.deleteTable(request);

איך הכל משתלב יחד

הנה דוגמת קוד מלאה ללא הערות.




const {Bigtable} = require('@google-cloud/bigtable');

const TABLE_ID = 'Hello-Bigtable';
const COLUMN_FAMILY_ID = 'cf1';
const COLUMN_QUALIFIER = 'greeting';
const INSTANCE_ID = process.env.INSTANCE_ID;

if (!INSTANCE_ID) {
  throw new Error('Environment variables for INSTANCE_ID must be set!');
}

const getRowGreeting = row => {
  return row.data[COLUMN_FAMILY_ID][COLUMN_QUALIFIER][0].value;
};

(async () => {
  try {
    const bigtableClient = new Bigtable();
    const instance = bigtableClient.instance(INSTANCE_ID);
    const table = instance.table(TABLE_ID);

    const {BigtableTableAdminClient} = require('@google-cloud/bigtable').v2;
    const adminClient = new BigtableTableAdminClient();
    const projectId = await adminClient.getProjectId();

    let tableExists = true;
    try {
      await adminClient.getTable({
        name: `projects/${projectId}/instances/${INSTANCE_ID}/tables/${TABLE_ID}`,
      });
    } catch (e) {
      if (e.code === 5) {
        tableExists = false;
      }
    }
    if (!tableExists) {
      console.log(`Creating table ${TABLE_ID}`);
      const {BigtableTableAdminClient} = require('@google-cloud/bigtable').v2;
      const adminClient = new BigtableTableAdminClient();
      const projectId = await adminClient.getProjectId();
      await adminClient.createTable({
        parent: `projects/${projectId}/instances/${INSTANCE_ID}`,
        tableId: TABLE_ID,
        table: {
          columnFamilies: {
            [COLUMN_FAMILY_ID]: {
              gcRule: {
                maxNumVersions: 1,
              },
            },
          },
        },
      });
    }

    console.log('Write some greetings to the table');
    const greetings = ['Hello World!', 'Hello Bigtable!', 'Hello Node!'];
    const rowsToInsert = greetings.map((greeting, index) => ({
      key: `greeting${index}`,
      data: {
        [COLUMN_FAMILY_ID]: {
          [COLUMN_QUALIFIER]: {
            timestamp: new Date(),
            value: greeting,
          },
        },
      },
    }));
    await table.insert(rowsToInsert);

    const filter = [
      {
        column: {
          cellLimit: 1, // Only retrieve the most recent version of the cell.
        },
      },
    ];

    console.log('Reading a single row by row key');
    const [singleRow] = await table.row('greeting0').get({filter});
    console.log(`\tRead: ${getRowGreeting(singleRow)}`);

    console.log('Reading the entire table');
    const [allRows] = await table.getRows({filter});
    for (const row of allRows) {
      console.log(`\tRead: ${getRowGreeting(row)}`);
    }

    console.log('Delete the table');
    const request = {
      name: `projects/${projectId}/instances/${INSTANCE_ID}/tables/${TABLE_ID}`,
    };
    await adminClient.deleteTable(request);
  } catch (error) {
    console.error('Something went wrong:', error);
  }
})();