Craft Document DB を利用する
Craft Document DB はCraft Functions内で利用できるドキュメントデータベースです。
Craft Functionsの MODULES.docDb から利用します。
データ構造
Craft Document DBでは、データを保存する単位をコレクションと呼びます。
- コレクション
- 同じスキーマを持つドキュメントの集合です
- 作成時にスキーマ(フィールド名・型・プライマリキー)を定義します
- 一度作成したスキーマは変更できません
- ドキュメント
- コレクションに格納される1件のデータです
- スキーマで定義したフィールドを持ちます
サンプルコード
export default async function (data, { MODULES }) { const { docDb } = MODULES;
// コレクションを作成する await docDb.createCollection({ collectionName: "users", schema: { userId: { type: "string", primaryKey: true }, name: { type: "string" }, age: { type: "number" }, department: { type: "string" }, isActive: { type: "boolean" }, tags: { type: "array", items: "string" }, }, });
// データを追加する await docDb.insert({ collectionName: "users", data: { userId: "user001", name: "山田太郎", age: 30, department: "engineering", isActive: true, tags: ["javascript", "react"], }, });
// データを検索する const result = await docDb.find({ collectionName: "users", where: { department: "engineering" }, orderBy: { age: "desc" }, take: 10, });
// データを更新する await docDb.update({ collectionName: "users", where: { userId: "user001" }, data: { age: 31 }, });
// データを削除する await docDb.delete({ collectionName: "users", where: { userId: "user001" }, });}メソッド
docDb モジュールで利用できるメソッドについて説明します。
createCollection
docDb.createCollection({ collectionName, schema });コレクションを作成します。
collectionName: コレクション名(英数字とアンダースコアのみ、先頭は英字)schema: フィールド定義のオブジェクト
スキーマには必ず1つのプライマリキーフィールド(primaryKey: true)を含めてください。プライマリキーは type: "string" でなければなりません。
利用可能なフィールド型
string: 文字列number: 数値boolean: 真偽値date: 日付array: 配列(itemsで要素型を指定)
配列型(array)について
配列型を使用する場合は、items プロパティで要素の型を指定します。
tags: { type: "array", items: "string", // 要素型: string, number, boolean, date のいずれか}- ネストした配列(配列の配列)はサポートされていません
- 配列型はプライマリキーとして使用できません
スキーマ定義の例
export default async function (data, { MODULES }) { const { docDb } = MODULES;
await docDb.createCollection({ collectionName: "users", schema: { userId: { type: "string", primaryKey: true, }, name: { type: "string", }, age: { type: "number", }, department: { type: "string", }, isActive: { type: "boolean", }, tags: { type: "array", items: "string", }, }, });}注意事項は次のとおりです。
- コレクション名はプロジェクト内で一意である必要があります
- スキーマには必ず1つのプライマリキーを定義してください(
primaryKey: true) - プライマリキーは必ず
type: "string"でなければなりません - 配列型(
type: "array")にはitemsで要素型を指定します - 一度作成したコレクションのスキーマは変更できません
insert
docDb.insert({ collectionName, data });コレクションにドキュメントを1件追加します。data にはプライマリキーフィールドを含める必要があります。
同じプライマリキーのドキュメントが既に存在する場合はエラーになります。
find
docDb.find({ collectionName, where, orderBy, take, cursor });条件を指定してドキュメントを検索します。
collectionName: 検索対象のコレクション名where: 検索条件(省略時は条件なし)orderBy: ソート条件(省略時はソートなし)take: 取得件数(省略時は10件、最大1,000件)cursor: ページネーション用カーソル(省略時は先頭から取得)
戻り値は { data, nextCursor, hasMore } です。
data: ドキュメントの配列nextCursor: 次ページのカーソル(最終ページの場合はnull)hasMore: 次ページが存在するかどうか
where で使える演算子
比較演算子
eq: 等しいgt: より大きいgte: 以上lt: より小さいlte: 以下
配列演算子
has: 配列に特定の値が含まれるかhasAny: 配列に指定した値のいずれかが含まれるか
// 等価検索{ where: { department: "engineering" } }
// 範囲検索{ where: { age: { gte: 20, lte: 40 } } }
// 配列検索{ where: { tags: { has: "javascript" } } }{ where: { tags: { hasAny: ["javascript", "typescript"] } } }複数条件を指定するとAND検索になります。OR条件はサポートされていないため、複数回クエリを実行して結果をマージしてください。
ページネーション
// 最初のページconst firstPage = await docDb.find({ collectionName: "users", where: { department: "engineering" }, take: 10,});
// 次のページif (firstPage.nextCursor) { const nextPage = await docDb.find({ collectionName: "users", where: { department: "engineering" }, take: 10, cursor: firstPage.nextCursor, });}update
docDb.update({ collectionName, where, data });ドキュメントを更新します。where にはプライマリキーを含める必要があります。
data に指定したフィールドのみが更新されます(指定しなかったフィールドは変更されません)。
delete
docDb.delete({ collectionName, where });ドキュメントを削除します。where にはプライマリキーを含める必要があります。
複合インデックス
単一フィールドでの等価検索・範囲検索・ソートはインデックスなしで実行できます。
複数フィールドを組み合わせるクエリ(例: フィールドAで絞り込み + フィールドBでソート)には、KARTE管理画面から複合インデックスを作成してください。
インデックスなしで実行可能なクエリ
// 等価条件のみ{ where: { department: "engineering", isActive: true } }
// 単一フィールドでのソート{ orderBy: { age: "desc" } }
// 単一フィールドでの範囲検索{ where: { age: { gte: 30 } } }
// 範囲検索 + 同一フィールドでのソート{ where: { age: { gte: 30 } }, orderBy: { age: "desc" } }複合インデックスが必要なクエリ
// 等価条件 + 異なるフィールドでのソート → [department (ASCENDING), age (DESCENDING)]{ where: { department: "engineering" }, orderBy: { age: "desc" } }
// 複数フィールドでの範囲検索 → [age (ASCENDING), salary (ASCENDING)]{ where: { age: { gte: 30 }, salary: { gte: 50000 } } }
// 範囲検索 + 異なるフィールドでのソート → [age (ASCENDING), name (ASCENDING)]{ where: { age: { gte: 30 } }, orderBy: { name: "asc" } }
// 複数フィールドでのソート → [department (ASCENDING), age (DESCENDING)]{ orderBy: { department: "asc", age: "desc" } }複数の範囲検索を使用する場合、内部的に各フィールドに対して昇順のorderByが適用されます。
インデックスの作成方法
KARTE管理画面の[すべてのメニュー > Craft > ドキュメントデータベース]から「インデックス」タブを開き、作成します。
- 最大10フィールドまで指定可能です
- フィールドタイプは次の通りです
order:ASCENDINGまたはDESCENDINGでソート順を指定arrayConfig:CONTAINSで配列要素の検索を指定
インデックス作成のヒント
- よく使うクエリパターンを特定し、それに対してインデックスを作成してください
- インデックスの作成には数分〜数十分かかることがあります
- 使用していないインデックスはストレージコストがかかるため、定期的に見直してください