LoginSignup
1
0

More than 3 years have passed since last update.

Azure Cosmos で無料で作るハイスコアDB(2) : APIとデータモデルとAzureテーブル

Posted at

はじめに

Azure Cosmos DBはただのNoSQL DBかと思い、前回の記事で で無料でハイスコアDBを作り始めたが、Table Api を使わないと期待する実装ができなそうに思え Table Api を調べることにした。

結論を先に述べておくと、Table Api には ソート機能 がないためハイスコアDBとしては使えなかった。

APIとデータモデル

Azure Cosmos DB では、DBアカウント作成時にAPIとデータモデルの種類が選択できる。

種類 内容
コア(SQL) jsonで保存したデータを、SQLの様な文法でqueryしアクセスする
MongoDB 用 Azure Cosmos DB API Azure Cosmos DB の MongoDB 用 API
Cassandra Azure Cosmos DB の Cassandra API の概要
Azure テーブル Azure Cosmos DB の概要:テーブル API
Gremlin(グラフ) Azure Cosmos DB での Gremlin API の概要

MongoDB, Cassandra は、同じくNoSQL DB。元々利用していれば同じインターフェース(API)で使えて移行が容易とのこと。どちらも利用していなかったので詳細は省略。
Gremlinは、グラフデータベース。今回の要件に対しては意識が高すぎるので詳細は省略。

コア(SQL)で作成したDBをAzure Portal のコンソールから確認すると生のjsonが表示され「何か違うな」と思いAzure テーブルにしたが、そこは気にせずにコア(SQL)にしておけばよかったが後の祭り。

Azureテーブル

PartitionKey, RowKey を持つ、Key-Value Store。
Azure Portal のコンソールから確認すると、各項目をヘッダに持つテーブルが表示され「俺の知ってるDBってこれだよな」という安心感があった。また、Apiもシンプルで学習コストも低く見えたので作業を進めた。

table-api.png

※データエクスプローラ(AZURE TABLE API):よく見るDBっぽい何かで安心感がある画面

create, insert, update と順調に作業を進めたが、read する際に sort ができないことに気づいた。
よって本プロジェクトではAzureテーブルは利用しない事としたが、せっかく調べたので記録として残しておくことにした。

test.js
const storage = require('azure-storage')
const client = storage.createTableService('接続文字列')
const eg = storage.TableUtilities.entityGenerator

//
//
// テーブル作成(テーブルのスキーマ定義は行わない)
//
//
client.createTableIfNotExists('<テーブル名>', (error, result) => {
  // 処理が終了するとコールバックが呼ばれる。
})

//
//
// レコードの登録/更新。
//
//

// 登録時に型指定も行う。
const entry = {
PartitionKey: eg.String('<PartitionKeyの値>'),
RowKey: eg.String('<RowKeyの値>'),
no: eg.Int64(1) // 任意の項目
}
client.insertOrReplaceEntity('<テーブル名>', entry, (error, result) => {
  // 処理が終了するとコールバックが呼ばれる。
})

//
//
// 任意のレコードを取得
//
//
client.retrieveEntity('<PartitionKeyの値>', '<RowKeyの値>', key, (error, result) => {
  // result.entry に値が入っている
  // 値は<項目名>._ に入っている
  // console.log(result.entry.no._)   // 1
})

//
//
// TableQuery を利用して、任意のPartition のレコードを取得
//
//

// 上位10件スコア取得、ではなく登録順に10件取得
const q = new storage.TableQuery().select('name', 'score').top(10)

client.queryEntities('scores', q, null, (error, result) => {
  if(error) {
    console.error(error)      
  } else {
    const entries = result.entries
    for(const e of entries) {
      console.log(e.name._, e.score._)
    }
  }
})


TableQueryが提供しているインターフェイス(2020/10/10時点)

azure-storage.d.ts

// コメント除去して抜粋

export interface TableQuery {
  select(...args: string[]): TableQuery;
  select(args: string[]): TableQuery;

  top(top: number): TableQuery;

  where(condition: string, ...args: any[]): TableQuery;
  and(condition: string, ...args: any[]): TableQuery;
  or(condition: string, ...args: any[]): TableQuery;

  toQueryObject(): Object;
}

export var TableQuery: {
  new(): TableQuery;

  int32Filter(propertyName: string, operation: string, value: string | number): string;
  int64Filter(propertyName: string, operation: string, value: string | number): string;
  doubleFilter(propertyName: string, operation: string, value: string | number): string;
  booleanFilter(propertyName: string, operation: string, value: boolean | string): string;
  dateFilter(propertyName: string, operation: string, value: Date | string): string;
  guidFilter(propertyName: string, operation: string, value: string | any): string;
  binaryFilter(propertyName: string, operation: string, value: Buffer | string): string;
  stringFilter(propertyName: string, operation: string, value: string): string;
  combineFilters(filterA: string, operatorString: string, filterB: string): string;
};

おわりに

NoSQLは、RDBよりチョロい上に無料という思い込みで作業を開始したが、CosmosDBが提供するサービスは想像以上に高機能だった。
MongoDBやCassandraを利用していたのであれば低い学習コストで移行できるかもしれない。

distinctorder by ができるようでしたらご指摘頂けますと助かります。

※作業開始前にドキュメントはよく読もう。

1
0
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
1
0