Docs Menu
Docs Home
/
MongoDB マニュアル
/ / /

埋め込みドキュメントによる 1 対多の関係のモデル化

項目一覧

  • Overview
  • 埋め込みドキュメント パターン
  • サブセット パターン

このページでは、 埋め込みドキュメントを使用して接続されたデータ間の 1 対多の関係を記述するデータモデルについて説明します。 接続されたデータを単一のドキュメントに埋め込むと、データを取得するために必要な読み取り操作の数を減らすことができます。 一般に、アプリケーションが 1 回の読み取り操作で必要な情報をすべて受け取れるようにスキーマを構成する必要があります。

パターンと複数のアドレス関係をマッピングする次の例を考えてみましょう。 この例では、多くのデータ エンティティを別のデータ エンティティに関連して表示する必要がある場合に、参照よりも埋め込みの利点が示されています。 patronaddressデータ間のこの 1 対多の関係では、 patronには複数のaddressエンティティがあります。

正規化されたデータモデルでは、 addressドキュメントにpatronドキュメントへの参照が含まれています。

// patron document
{
_id: "joe",
name: "Joe Bookreader"
}
// address documents
{
patron_id: "joe", // reference to patron document
street: "123 Fake Street",
city: "Faketon",
state: "MA",
zip: "12345"
}
{
patron_id: "joe",
street: "1 Some Other Street",
city: "Boston",
state: "MA",
zip: "12345"
}

アプリケーションがname情報を持つaddressデータを頻繁に取得する場合は、参照を解決するためにアプリケーションは複数のクエリを発行する必要があります。 より最適なスキーマは、次のドキュメントのように、 patronデータにaddressデータ エンティティを埋め込むことです。

{
"_id": "joe",
"name": "Joe Bookreader",
"addresses": [
{
"street": "123 Fake Street",
"city": "Faketon",
"state": "MA",
"zip": "12345"
},
{
"street": "1 Some Other Street",
"city": "Boston",
"state": "MA",
"zip": "12345"
}
]
}

埋め込みデータ モデルを使用すると、アプリケーションは 1 回のクエリで完全なパッチ情報を検索できます。

埋め込みドキュメント パターンに関する潜在的な問題は、埋め込みフィールドが無制限の場合、大きなドキュメントにつながる可能性があることです。 この場合、サブセット パターンを使用すると、埋め込みデータ全体ではなく、アプリケーションに必要なデータのみにアクセスできます。

製品のレビューリストを持つeコマース サイトを考えてみましょう。

{
"_id": 1,
"name": "Super Widget",
"description": "This is the most useful item in your toolbox.",
"price": { "value": NumberDecimal("119.99"), "currency": "USD" },
"reviews": [
{
"review_id": 786,
"review_author": "Kristina",
"review_text": "This is indeed an amazing widget.",
"published_date": ISODate("2019-02-18")
},
{
"review_id": 785,
"review_author": "Trina",
"review_text": "Nice product. Slow shipping.",
"published_date": ISODate("2019-02-17")
},
...
{
"review_id": 1,
"review_author": "Hans",
"review_text": "Meh, it's okay.",
"published_date": ISODate("2017-12-06")
}
]
}

レビューは、逆の時系列でソートされます。 ユーザーが製品ページにアクセスすると、アプリケーションは最新の 10 件のレビューを読み込みます。

製品のレビューをすべて保存する代わりに、 コレクションを 2 つのコレクションに分割できます。

  • productコレクションには、製品の最新 10 件のレビューを含む、各製品に関する情報が保存されています。

    {
    "_id": 1,
    "name": "Super Widget",
    "description": "This is the most useful item in your toolbox.",
    "price": { "value": NumberDecimal("119.99"), "currency": "USD" },
    "reviews": [
    {
    "review_id": 786,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    ...
    {
    "review_id": 777,
    "review_author": "Pablo",
    "review_text": "Amazing!",
    "published_date": ISODate("2019-02-16")
    }
    ]
    }
  • reviewコレクションにはすべてのレビューが保存されています。 各レビューには、それが書き込まれた製品への参照が含まれています。

    {
    "review_id": 786,
    "product_id": 1,
    "review_author": "Kristina",
    "review_text": "This is indeed an amazing widget.",
    "published_date": ISODate("2019-02-18")
    }
    {
    "review_id": 785,
    "product_id": 1,
    "review_author": "Trina",
    "review_text": "Nice product. Slow shipping.",
    "published_date": ISODate("2019-02-17")
    }
    ...
    {
    "review_id": 1,
    "product_id": 1,
    "review_author": "Hans",
    "review_text": "Meh, it's okay.",
    "published_date": ISODate("2017-12-06")
    }

productコレクションに最新の 10 件のレビューを保存すると、 productコレクションの呼び出しでは全体的なデータの必要なサブセットのみが返されます。 ユーザーが追加のレビューを表示したい場合、アプリケーションはreviewコレクションを呼び出します。

Tip

データを分割する場所を検討する場合、データの最も頻繁にアクセスする部分は、アプリケーションが最初に読み込むコレクションに含める必要がありGo 。 この例では、スキーマは 10 個のレビューに分割されます。これは、デフォルトでアプリケーションに表示されるレビュー数であるためです。

Tip

以下も参照してください。

サブセット パターンを使用してコレクション間の 1 対 1 の関係をモデル化する方法については、「埋め込みドキュメントによる 1 対 1 の関係のモデル化 」を参照してください。

アクセス頻度の高いデータを含む小さいドキュメントを使用すると、 ワーキングセット の全体サイズは縮小されます。 これらのドキュメントが小さいと、アプリケーションが最も頻繁にアクセスするデータの読み取りパフォーマンスが向上します。

ただし、サブセット パターンではデータの重複が発生します。 この例では、レビューはproductコレクションとreviewsコレクションの両方で保持されています。 各コレクション間でレビューが一貫していることを確認するために、追加の手順を実行する必要があります。 たとえば、カスタマーがレビューを編集する場合、アプリケーションは 2 つの書込み操作を行う必要があります。1 つはproductコレクションを更新し、1 つはreviewsコレクションを更新します。

また、アプリケーションにロジックを実装して、 productコレクション内のレビューが常にその製品の最新の 10 件のレビューになるようにする必要があります。

製品レビューに加えて、サブセット パターンは以下の保存にも適しています。

  • 最新のコメントまたは最高評価のコメントのみをデフォルトで表示するブログ記事のコメント。

  • 映画内で、最大のロールを持つキャスト メンバーのみをデフォルトで表示する場合。

戻る

1 対 1 の埋め込みドキュメント