Open4
[DynamoDB × Node.js] DynamoDB向けライブラリ調査

はじめに
AWS SDKによるDynamoDB操作の場合、操作がやや複雑に感じた。
そのため、検索時の指定だったり、1MB制限に対するページング処理を簡単に行えるライブラリがないか調査進めたい。
調査対象のライブラリ/機能など
ライブラリ/機能 | 概要 | URL |
---|---|---|
Dynamoose | DynamoDB用のモデリングツール(データや情報の構造・関係性を設計・可視化するためのツール) | 公式URL |
ElectroDB | 単一のDynamoDBテーブル内で複数のエンティティや複雑な階層関係を容易に管理できるDynamoDBライブラリ | 公式URL |
dynamodb-toolbox | DynamoDBおよびTypeScript 用の軽量で型セーフなクエリビルダー | 公式URL |
PartiQL | DynamoDB用のSQL互換クエリ言語(DynamoDB標準機能) | 公式URL |

まとめ
- 後述

Dynamoose使い方調査
基本概念
- Schema:DynamoDBに保存するデータの項目名や型、必須属性などを定義する設計図
- Model : SchemaをもとにDynamoDBのテーブルを表し、CRUD操作を実行するためのインターフェイス
初期設定
- インストール(npm)
npm install --save dynamoose
- インポート(CommonJS)
const dynamoose = require("dynamoose");
スキーマ定義例
const HogeSchema = new dynamoose.Schema({
pk_item: { type: String, hashKey: true }, // PK相当の項目に"hashKey"
sk_item,: { type: String, rangeKey: true }, // SK相当の項目に"rangeKey"
other_item1: { type: String },
other_item2: { type: Number },
other_item3: { type: Boolean },
other_item4: { type: Array, schema: [String] },
});
モデル定義例
// フォーマット例: const モデル変数名 = dynamoose.model("テーブル名", "スキーマ", テーブルオプション);
// {create:false}に関するドキュメント: https://dynamoosejs.com/guide/Table
const HogeModel = dynamoose.model("human_table", HogeSchema, {create: false});
Scan例
// フォーマット例: const 結果格納用変数名 = モデル変数.scan().exec();
const HogeModelItems = await HogeModel.scan().exec();
Query例
// PKを指定してクエリする
const queryItem = await HogeModel
.query("PK設定のカラム名")
.eq("任意の値")
.exec();
console.log(queryItem);
// PKとSKを指定してクエリする
const queryItem = await HogeModel
.query("PK設定のカラム名")
.eq("任意の値")
.where("SK設定のカラム名")
.eq("任意の値")
.exec();
console.log(queryItem);
// GSIを指定してクエリする
const queryItem = await HogeModel
.query("GSIのPKカラム名")
.eq("任意の値")
.where("GSIのSKカラム名")
.eq("任意の値")
.using("GSI名")
.exec();
console.log(queryItem);

ElectroDB使い方調査
基本概念
- Entities:アプリケーションで扱う「業務上の対象(例:ユーザー、注文、契約)」を定義する単位。Entityごとにスキーマや操作を定義する。
- Services:複数のEntityをまとめる単位。
- Schema:Entityの構造を定義するもの。
- Attributes: Schema内のフィールド。RDBのカラムに相当。
- Indexes: データアクセスを最適化するためのDynamoDBのパーティションキー/ソートキーやGSIの設計を定義する。
- Collections: 複数のEntityをまたいで共通のアクセスパターンを提供する仕組み。
初期設定
- インストール(npm)
npm install electrodb --save
- インポート(CommonJS)
const { Entity, Service } = require("electrodb");
Entity定義例
const { DynamoDBClient } = require("@aws-sdk/client-dynamodb");
const { DynamoDBDocumentClient } = require("@aws-sdk/lib-dynamodb");
const { Entity } = require("electrodb");
const client = DynamoDBDocumentClient.from(new DynamoDBClient({ region: "ap-northeast-1" }));
// DynamoDB上のテーブル定義と属性やPKなどを一致させる必要あり
const HogeEntity = new Entity(
{
model: {
entity: "hoge",
version: "1",
service: "default",
},
attributes: {
pk_item: {
type: "string",
},
sk_item: {
type: "number",
},
other_item1: {
type: "string",
},
other_item2: {
type: "number",
},
other_item3: {
type: "boolean",
},
other_item4: {
type: "list",
items: { type: "string" },
},
},
indexes: {
pk_item: {
pk: {
field: "pk_item",
composite: ["pk_item"],
}
},
},
},
{ table: "hoge_tbl", client }, // <= DynamoDB上のテーブル名を指定
);
Scan例
const scanItem = await HogeEntity.scan.go({ ignoreOwnership: true });
console.log(scanItem);
Query例
// PKを指定してクエリする
const queryItem = await HogeEntity.get({ PK設定のカラム名: "任意の値" }).go({ ignoreOwnership: true });
console.log(queryItem);
// PKとSKを指定してクエリする
const queryItem = await HogeEntity.get({ PK設定のカラム名: "任意の値", SK設定のカラム名: "任意の値" }).go({ ignoreOwnership: true });
console.log(queryItem);