MongoDB でスキーマを定義する

Tahseen Tauseef 2024年2月15日
  1. MongoDB のスキーマ
  2. MongoDB でスキーマを設計する際の考慮事項
  3. MongoDB でスキーマを定義する
  4. MongoDB レルムを使用してスキーマを適用する
MongoDB でスキーマを定義する

この記事では、MongoDB スキーマとその定義方法について説明します。

MongoDB のスキーマ

データの構造と内容は、JSON オブジェクトであるスキーマによって定義されます。 JSON スキーマ標準を拡張する Realm の BSON スキーマを使用して、アプリのデータ モデルを設計し、ドキュメントが作成、変更、または削除されるたびにドキュメントを検証できます。

正確な値の代わりに、スキーマはさまざまな種類のデータを表します。 多くの組み込みスキーマ タイプが Realm でサポートされています。 テキスト、数値などのプリミティブと、オブジェクトや配列などの構造型を組み合わせて、カスタム オブジェクト型を表すスキーマを形成できます。

たとえば、車に関するデータの基本的なスキーマと、スキーマに準拠するいくつかの車のオブジェクトを以下に示します。

スキーマ:

{
  "title": "car",
  "required": [
    "_id",
    "year",
    "make",
    "model",
    "kilometers"
  ],
  "properties": {
    "_id": { "bsonType": "objectId" },
    "year": { "bsonType": "string" },
    "make": { "bsonType": "string" },
    "model": { "bsonType": "string" },
    "kilometers": { "bsonType": "number" }
  }
}

オブジェクト:

{
  "_id": ObjectId("5af712eff26b29dc5c51c60f"),
  "year": "2022",
  "make": "Honda",
  "model": "Civic",
  "kilometers": 123
}
{
  "_id": ObjectId("5af714eff24b294c5251cf04"),
  "year": "2016",
  "make": "Honda",
  "model": "City",
  "kilometers": 135794
}

スキーマは、アプリケーションのデータ モデル仕様です。 Realm は、定義したスキーマに準拠するデータを操作するための追加のツールとサービスを提供します。

Realm の多くのアプリケーション サービスはスキーマを使用します。

  1. Realm と MongoDB Atlas の間でデータを同期するために、Realm Sync はスキーマを使用します。 スキーマに基づいて、慣用的な SDK オブジェクト モデルを開発することもできます。
  2. GraphQL API は、スキーマを自動的に使用して、タイプ、クエリ、およびミューテーションを自動的に含む GraphQL スキーマを生成します。 スキーマで定義された型を参照するカスタム リゾルバーをアプリの API に追加できます。
  3. 各リクエストの前後に、データ アクセス ルールにより、データがスキーマに準拠していることを確認します。 さらに、ドキュメントが検証に失敗した場合、レルムはリクエスト全体を防止またはロールバックします。

MongoDB でスキーマを設計する際の考慮事項

  1. ユーザーの要件に従ってスキーマを設計します。
  2. オブジェクトを一緒に使用する場合は、それらを 1つのドキュメントに結合します。 必要に応じてそれらを分離します (ただし、結合する必要がないことを確認してください)。
  3. ディスク容量は計算時間よりも安価であるため、データを複製します (ただし制限があります)。
  4. 読み込み中ではなく、書き込み中に結合を行います。
  5. 最も頻繁に使用されるケースに合わせてスキーマを最適化します。
  6. スキーマで複雑な集計を行います。

これを説明する例を以下に示します。

クライアントがブログまたは Web サイト用のデータベース設計を必要としており、RDBMS と MongoDB のスキーマ設計の違いに気付いたとします。 Web サイトには、次の要件があります。

  1. すべての投稿には、固有のタイトル、説明、および URL があります。
  2. すべての投稿に 1つまたは複数のタグを付けることができます。
  3. すべての投稿には、発行者の名前といいねの総数が表示されます。
  4. すべての投稿には、ユーザーのコメントとその名前、メッセージ、日時、いいね! が含まれます。
  5. 各投稿には、コメントがない場合もあれば、複数のコメントがある場合もあります。

RDBMS スキーマでは、上記の要件に対応する設計には、少なくとも 3つのテーブルが含まれます。

RDBMS スキーマ設計

MongoDB スキーマでは、デザインには 1つのコレクション ポストと次の構造が含まれます。

{
  _id: POST-ID
  title: TITLE-OF-POST,
  description: POST-DESCRIPTION,
  by: POST-BY,
  url: URL-OF-POST,
  tags: [TAG1, TAG2],
  likes: TOTAL-LIKES,
  comments: [
    {
        user: 'COMMENT-BY',
        message: TEXT,
        dateCreated: DATE-TIME,
        like: LIKES
    },
    {
        user: 'COMMENT-BY',
        message: TEXT,
        dateCreated: DATE-TIME,
        like: LIKES
    }
  ]
}

したがって、RDBMS では、3つのテーブルを組み合わせてデータを表示する必要があります。 ただし、MongoDB では、データは 1つのコレクションからのみ表示されます。

MongoDB でスキーマを定義する

型の属性を指定する追加のスキーマは、ルート レベルのコレクション スキーマにあります。 各ルートレベルのスキーマは、次のような object スキーマです。

{
  "bsonType": "object",
  "title": "<Type Name>",
  "required": ["<Required Field Name>", ...],
  "properties": {
    "<Field Name>": <Schema>
  }
}

ユーザーは、次のサポートされているスキーマ タイプのいずれかを使用して、オブジェクトのプロパティを構成できます。

  1. オブジェクト
  2. 配列
  3. ストリング
  4. ブール値
  5. オブジェクト ID
  6. バイナリデータ
  7. 混合
  8. 設定する
  9. 辞書

MongoDB レルムを使用してスキーマを適用する

MongoDB コレクションに対するすべての書き込み操作 (挿入、更新、および削除) は、MongoDB Realm によってコレクション スキーマに対して検証されます。

また、各リクエストの前後に各ドキュメントを調べて、すべてのプロパティがスキーマと一致しており、無効な変更が行われていないことを確認します。

書き込み操作をクラスターにコミットする前に、Realm はすべてのドキュメント書き込みの結果をチェックし、それらをスキーマと比較します。

MongoDB Realm は、リクエストに変更を加えることなく、リクエストの書き込み操作の結果がスキーマに適合しない場合、ユーザーにエラーを配信します。

この例を以下に示します。 コレクションには次のスキーマがあります。

{
  "title": "person",
  "properties": {
    "_id": {"bsonType": "objectId" },
    "name": {"bsonType": "string" }
    }
}

すべてのフィールドへの完全なアクセス権を持つユーザーが、特定のドキュメントの name フィールドを変更したいと考えています。 彼らは次のことについて尋ねます。

collection.updateOne(
  { "_id": BSON.ObjectId("5ae782e48f25b9dc5c51c4d0") },
  { "$set": { "name": 22 } }
)

クエリは、name の値を数値 22 に設定しようとします。 それにもかかわらず、スキーマは値が文字列であることを指定します。

ユーザーがドキュメントを更新する権限を受け取ったとしても、書き込み結果がスキーマに準拠していないため、MongoDB Realm はこの書き込み操作を拒否します。