Node.js 版 Hello World

本代码示例是一个在 Node.js 上运行的“hello world”应用,说明如何完成以下任务:

  • 设置身份验证
  • 连接到 Bigtable 实例。
  • 新建一个表。
  • 将数据写入表中。
  • 重新读取这些数据。
  • 删除表。

设置身份验证

如需在本地开发环境中使用本页面上的 Node.js 示例,请安装并初始化 gcloud CLI,然后使用您的用户凭证设置应用默认凭证。

  1. Install the Google Cloud CLI.

  2. If you're using an external identity provider (IdP), you must first sign in to the gcloud CLI with your federated identity.

  3. To initialize the gcloud CLI, run the following command:

    gcloud init
  4. If you're using a local shell, then create local authentication credentials for your user account:

    gcloud auth application-default login

    You don't need to do this if you're using Cloud Shell.

    If an authentication error is returned, and you are using an external identity provider (IdP), confirm that you have signed in to the gcloud CLI with your federated identity.

如需了解详情,请参阅 Set up authentication for a local development environment。 如需了解详情,请参阅身份验证文档中的为本地开发环境设置 ADC

运行示例

此代码示例使用 Node.js 版 Google Cloud 客户端库Bigtable 软件包与 Bigtable 通信。

要运行此示例程序,请按照 GitHub 上的示例说明执行操作。

将 Cloud 客户端库与 Bigtable 搭配使用

示例应用会连接到 Bigtable 并演示一些简单操作。

需要客户端库

本示例需要使用 @google-cloud/bigtable 模块,该模块可提供 Bigtable 类。

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

连接到 Bigtable

要连接到 Bigtable,请创建一个新的 Bigtable 对象。然后调用该对象的 instance() 方法,以获取表示您的 Bigtable 实例的 Instance 对象。

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

创建表

调用实例的 table() 方法,以获取表示“hello world”问候语表的 Table 对象。如果该表不存在,则调用表的 create() 方法,以创建包含一个列族且该列族会为每个值保留一个版本的表。

const table = instance.table(TABLE_ID);
const [tableExists] = await table.exists();
if (!tableExists) {
  console.log(`Creating table ${TABLE_ID}`);
  const options = {
    families: [
      {
        name: COLUMN_FAMILY_ID,
        rule: {
          versions: 1,
        },
      },
    ],
  };
  await table.create(options);
}

将行写入表

使用问候语字符串数组为表创建一些新行:请调用该数组的 map() 方法,以创建表示行的新对象数组,然后调用表的 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');
await table.delete();

综合应用

以下为不包含注释的完整代码示例。




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 [tableExists] = await table.exists();
    if (!tableExists) {
      console.log(`Creating table ${TABLE_ID}`);
      const options = {
        families: [
          {
            name: COLUMN_FAMILY_ID,
            rule: {
              versions: 1,
            },
          },
        ],
      };
      await table.create(options);
    }

    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');
    await table.delete();
  } catch (error) {
    console.error('Something went wrong:', error);
  }
})();