Join us Sept 17 at .local NYC! Use code WEB50 to save 50% on tickets. Learn more >
MongoDB Event
Docs Menu
Docs Home
/
データベース マニュアル
/ / /

属性パターンでデータをグループ化する

属性パターンは、特にフィールドが共通の特徴を持つ場合に、多数の類似フィールドを持つドキュメントを整理するスキーマ設計パターンです。類似フィールドのこれらのサブセットに対してソートまたはクエリを実行する必要がある場合は、属性パターンによってスキーマを最適化 できます。ドキュメントごとの複数の類似フィールドをキー値のサブドキュメントに統合することで、ドキュメントのインデックス作成が容易になります。属性パターンによって複数の類似フィールドに複数のインデックスを作成する代わりに、作成数を少なくできるため、クエリの高速化と書込みが容易になります。

コレクションに次の条件のいずれかに当てはまる場合は、 属性パターンを使用します。

  • ソートまたはクエリを実行したい共有特徴を持つ多数の類似フィールドを含む大きなドキュメントがある。

  • ドキュメントの小さなサブセットには、ソートに必要なフィールドが含まれています。

映画のコレクションを検討します。コレクション内の一般的なドキュメントは次のようになります。

db.movies.insertOne(
{
"_id": 1,
"title": "Star Wars",
"runtime": 121,
"directors": ["George Lucas"],
release_US: ISODate("1977-05-20T01:00:00+01:00"),
release_France: ISODate("1977-10-19T01:00:00+01:00"),
release_Italy: ISODate("1977-10-20T01:00:00+01:00"),
release_UK: ISODate("1977-12-27T01:00:00+01:00")
}
)

上記のドキュメントには、複数の国のリリース日フィールドに注意してください。リリース日を検索する場合は、多くのフィールドを一度に調べる必要があります。属性パターンがない場合、リリース日の検索をすばやく実行するには、moviesコレクションにいくつかのインデックスを作成する必要があります。

db.movies.createIndex({ release_US: 1 });
db.movies.createIndex({ release_France: 1 });
db.movies.createIndex({ release_Italy: 1 });
db.movies.createIndex({ release_UK: 1 });

ただし、インデックスは高価であり、特に書込み操作のパフォーマンスを低下させる可能性があります。次の手順では、さまざまなリリース日の情報サブセットを配列に移動して、インデックスの必要性を減らすことで、moviesコレクションに属性パターンを適用する方法を示しています。

1

スキーマを再構成して、さまざまなリリース日フィールドをキーと値のペアの配列にします。

db.movies.insertOne(
{
"_id": 1,
"title": "Star Wars",
"runtime": 121,
"directors": ["George Lucas"],
releases: [
{
location: "USA",
date: ISODate("1977-05-20T01:00:00+01:00")
},
{
location: "France",
date: ISODate("1977-10-19T01:00:00+01:00")
},
{
location: "Italy",
date: ISODate("1977-10-20T01:00:00+01:00")
},
{
location: "UK",
date: ISODate("1977-12-27T01:00:00+01:00")
}
]
}
)
2

次に、releases 配列に 1 つのインデックスを作成できます。このインデックスは、さまざまな国のリリース日フィールドに対するクエリを最適化します。

db.movies.createIndex({ releases: 1 });

ドキュメントに同じ特性または類似の特性を追跡する複数のフィールドがある場合、属性パターンによって類似するフィールドごとにインデックスを作成する必要がなくなります。同様のフィールドを配列に統合し、その配列にインデックスを作成することで、必要なインデックスの総数を減らし、クエリのパフォーマンスを向上させます。

属性パターンは、ドキュメントがアイテムの特性を説明する場合に役立ちます。衣料品などの一部の製品のサイズは、小、中、または大で表示される場合があります。同じコレクション内の他の製品はボリュームで表される場合もありますが、他の製品は物理的単位または重みで表される場合があります。

例、 の下のボトルネックのコレクションを考えてみましょう。属性パターンを使用しないドキュメントは次のようになります。

db.bottles.insertOne([
{
"_id": 1,
"volume_ml": 500,
"volume_ounces": 12
}
])

次のコードでは、属性パターン を bottlesコレクションに適用します。

db.bottles.insertOne([
{
"_id": 1,
specs: [
{ k: "volume", v: "500", u: "ml" },
{ k: "volume", v: "12", u: "ounces" },
]
}
])

最初のドキュメントの volume_ml フィールドと volume_ounces フィールドには同様の情報が含まれているため、上記のスキーマはそれらを 1 つのフィールドspecs に統合します。specsフィールドは、特定のサーバーの測定仕様に関する情報をグループ化します。kフィールドは測定対象を指定し、v は値を指定し、u は測定単位を指定します。

属性パターンを使用すると、異なる名前を持つ類似フィールドをグループ化することもできます。測定対象を指定する kフィールド のように、キーと値のペアで属性を指定することで、より幅広い類似フィールドを 1 つの配列に保存でき、データを効率的にクエリするために必要なインデックスの数を最小限に抑えることができます。

例、属性パターンを使用していない bottlesコレクション内の次のドキュメントを考えてみましょう。このドキュメントには、サーバー用の容量と高さの仕様が保存されています。

db.bottles.insertOne([
{
"_id": 1,
"volume_ml": 500,
"volume_ounces": 12,
"height_inches": 8
}
])

次のコードは、ドキュメントに属性パターン を適用します。volume_mlvolume_ouncesheight_inches フィールドはすべて specs 配列にグループ化されます。

db.bottles.insertOne([
{
"_id": 1,
specs: [
{ k: "volume", v: "500", u: "ml" },
{ k: "volume", v: "12", u: "ounces" },
{ k: "height", v: "8", u: "inches" }
]
}
])

kvu などのキーと値のペアを使用すると、配列に追加できるフィールドの柔軟性が向上します。配列に連結できるフィールドが多いほど、作成する必要があるインデックスが少なくなり、クエリのパフォーマンスが最大化されます。

戻る

外側のパターン

項目一覧