LoginSignup
15
14

More than 5 years have passed since last update.

Node.jsでBigQueryを叩いてみようと思ったら一瞬で終わった

Last updated at Posted at 2017-11-16

ちきさんです。

Node.jsでGCPのBigQueryに元々用意されているサンプルデータをクエリしてみようと思ってやってみたらあっさりできたのでメモを残します。

https://cloud.google.com/bigquery/create-simple-app-api?hl=ja#bigquery-simple-app-query-nodejs を参考にしました。

書いたTypeScriptのコードはこちら。

import * as BigQuery from '@google-cloud/bigquery'

const bigquery = BigQuery({
  credentials: require('./path/to/your-service-account-key.json')
});

const query: string = `
  select corpus, count(*) as unique_words 
  from publicdata.samples.shakespeare
  group by corpus
  order by unique_words desc
  limit 10;
`

const options = {
  query,
  useLegacySql: false,
}

/**
 * 実行計画
 */
bigquery
  .startQuery({ ...options, dryRun: true })
  .then(results => {
    const [job, apiResponse] = results
    const statistics = apiResponse.statistics
    console.log('見積もり(円):', billedAsYen(statistics.totalBytesProcessed))
    console.log(JSON.stringify(statistics, null, 2))
  })
  .catch(err => {
    console.error('ERROR:', err);
  })

/**
 * 実行
 */
bigquery
  .startQuery(options)
  .then(results => {
    const [job] = results
    return job.getQueryResults()
  })
  .then(results => {
    const [rows] = results
    console.log(JSON.stringify(rows, null, 2))
  })
  .catch(err => {
    console.error('ERROR:', err);
  })

// ↓適当に書いたので計算違ってるかも
function billedAsYen(bytesProcessed: number): number {
  const minBytesBilled: number = 1024 * 1024 * 10
  const bytes: number = minBytesBilled > bytesProcessed ? minBytesBilled : bytesProcessed
  const bytesAsTeraBytes: number = bytes / 1024 / 1024 / 1024 / 1024
  return bytesAsTeraBytes / 1 /* TB */ * 5 /* $ */ * 113 /* 円(ドル円相場) */
}

そして得られた結果はこちら。

実行計画の結果.json
{
  "creationTime": "1510853651921",
  "totalBytesProcessed": "2464625",
  "query": {
    "totalBytesProcessed": "2464625",
    "totalBytesBilled": "0",
    "cacheHit": true,
    "referencedTables": [
      {
        "projectId": "publicdata",
        "datasetId": "samples",
        "tableId": "shakespeare"
      }
    ],
    "schema": {
      "fields": [
        {
          "name": "corpus",
          "type": "STRING",
          "mode": "NULLABLE"
        },
        {
          "name": "unique_words",
          "type": "INTEGER",
          "mode": "NULLABLE"
        }
      ]
    },
    "statementType": "SELECT"
  }
}
実行の結果.json
[
  {
    "corpus": "hamlet",
    "unique_words": 5318
  },
  {
    "corpus": "kinghenryv",
    "unique_words": 5104
  },
  {
    "corpus": "cymbeline",
    "unique_words": 4875
  },
  {
    "corpus": "troilusandcressida",
    "unique_words": 4795
  },
  {
    "corpus": "kinglear",
    "unique_words": 4784
  },
  {
    "corpus": "kingrichardiii",
    "unique_words": 4713
  },
  {
    "corpus": "2kinghenryvi",
    "unique_words": 4683
  },
  {
    "corpus": "coriolanus",
    "unique_words": 4653
  },
  {
    "corpus": "2kinghenryiv",
    "unique_words": 4605
  },
  {
    "corpus": "antonyandcleopatra",
    "unique_words": 4582
  }
]

とても簡単でした。

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14