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

外側のパターンでデータをグループ化する

項目一覧

  • 始める前に
  • 長所
  • 短所
  • このタスクについて
  • 手順
  • アウトバウンドのしきい値を特定する
  • アウトバウンドの処理方法を決定する
  • 外側のドキュメントにインジケーターを追加する
  • 追加の売上を別のコレクションに保存
  • 結果
  • アウトバウンドの更新
  • 詳細

コレクションにほぼ同じサイズと形状のドキュメントが保存されている場合、大幅に異なるドキュメント(アウトバウンド)は、一般的なクエリのパフォーマンスの問題を発生させる可能性があります。

配列フィールドを保存するコレクションを検討します。 ドキュメントにコレクション内の他のドキュメントよりも多くの配列要素が含まれている場合は、スキーマ内でそのドキュメントを異なる方法で処理する必要がある場合があります。

外側のパターンを使用して、期待される形状と一致しないドキュメントをコレクションの残りの部分から分離します。 スキーマは引き続き同じデータすべてを保持しますが、一般的なクエリは単一の大きなドキュメントの影響を受けません。

アウトバウンドを処理するようにスキーマを変更する前に、アウトバウンド パターンの長所と懸念事項を検討してください。

外側のパターンにより、よく実行されるクエリのパフォーマンスが向上します。 一般的なドキュメントを返すクエリでは、アウトバウンド 大規模なドキュメントも返す必要はありません。

外側のパターンは、アプリケーション内のエッジケースも処理します。 たとえば、アプリケーションが通常、配列から50の結果を表示する場合、ユーザー エクスペリエンスを中断するような2 、 000の結果を含むドキュメントはありません。

外側のパターンでは、更新を処理するためにより複雑なロジックが必要になります。 データの更新が頻繁に必要な場合は、他のスキーマ設計パターンを検討してください。 詳しくは、「 Atlas のアップデート 」を参照してください。

書籍の売上を追跡するスキーマを考えてみましょう。 コレクション内の通常のドキュメントは次のようになります。

db.sales.insertOne(
{
"_id": 1,
"title": "Invisible Cities",
"year": 1972,
"author": "Italo Calvino",
"customers_purchased": [ "user00", "user01", "user02" ]
}
)

customers_purchased配列は無制限であるため、書籍を購入する顧客が多いほど配列は大きくなります。 ほとんどのドキュメントでは、店舗では特定の書籍の数倍の売上が予想されているため、問題にはなりません。

新しい人気の書籍が大量に購入されるとします。 現在のスキーマ設計ではドキュメントが肥大化し、パフォーマンスに悪影響が生じます。 この問題に対処するには、通常の販売額がないドキュメントに対して 外側のパターン を実装します。

1

スキーマの一般的なドキュメント構造を考慮すると、ドキュメントが除外数になるタイミングを特定できます。 このしきい値は、アプリケーションの UI が要求する値、またはドキュメントに対して実行するクエリ値に基づいています。

この例では、売上が50を超える書籍はアウトバウンドです。

2

大規模な配列を扱う場合、アウトバウンドを処理する一般的な方法は、しきい値を超える値を別のコレクションに保存することです。 50を超える売上のある書籍の場合は、余計なcustomers_purchased値を別のコレクションに保存します。

3

50を超える売上のある書籍の場合は、 has_extrasという新しいドキュメント フィールドを追加し、値をtrueに設定します。 このフィールドは、別の コレクションに保存されている売上が、さらにあることを示します。

db.sales.insertOne(
{
"_id": 2,
"title": "The Wooden Amulet",
"year": 2023,
"author": "Lesley Moreno",
"customers_purchased": [ "user00", "user01", "user02", ... "user49" ],
"has_extras": true
}
)
4

最初の50を超える売上を保存するには、 extra_salesというコレクションを作成します。 参照を使用して、 extra_salesコレクションのドキュメントをsalesコレクションにリンクします。

db.extra_sales.insertOne(
{
"book_id": 2,
"customers_purchased_extra": [ "user50", "user51", "user52", ... "user999" ]
}
)

The outlier pattern prevents atypical documents from impacting query performance. 結果として得られるスキーマは、販売の完全なリストを維持しながら、 コレクション内の大きなドキュメントを回避します。

書籍とその書籍を購入したすべてのユーザーに関する情報を表示するアプリケーション ページを考えてみましょう。 外側のパターンを実装すると、ページにはほとんどの書籍(一般的なドキュメント)の情報がすばやく表示されます。

一般的な書籍(アウトバウンド)の場合、アプリケーションはbook_idextra_salesコレクションで追加のクエリを実行します。 このクエリのパフォーマンスを向上させるには、 book_idフィールドにインデックスを作成します。

対象外のドキュメントのアップデートは、通常のドキュメントとは異なる方法で処理する必要があります。 更新を実行するために使用するロジックは、スキーマの設計によって異なります。

前述のスキーマのアウトバウンドのアップデートを実行するには、次のアプリケーション ロジックを実装します。

  • 更新対象のドキュメントで、has_extrastrue に設定されているかどうかを確認します。

    • has_extrasが欠落している場合、またはfalseの場合は、新しい購入をsalesコレクションに追加します。

      • 結果のcustomers_purchased配列に50を超える要素が含まれている場合は、 has_extrastrueに設定します。

    • has_extrastrueの場合、対応するbook_idsales_extrasコレクションに新しい購入を追加します。

  • バケット パターンでデータをグループ化する

  • 無制限の配列を避ける

  • 埋め込みデータと参照の比較

  • 計算されたデータを保存する

戻る

バケット パターン