コンテンツにスキップ

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 で配列要素の検索を指定

インデックス作成のヒント

  • よく使うクエリパターンを特定し、それに対してインデックスを作成してください
  • インデックスの作成には数分〜数十分かかることがあります
  • 使用していないインデックスはストレージコストがかかるため、定期的に見直してください

API リファレンス

リファレンス