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

$bucket(集計)

項目一覧

  • 定義
  • Considerations
  • 構文
  • 動作
$bucket

バージョン 3.4 で追加

指定された式とバケット境界に基づいて、受信したドキュメントをバケットと呼ばれるグループに分類し、各バケットごとに 1 つのドキュメントを出力します。各出力ドキュメントには、バケットの包含的な下限を指定する値を持つ _id フィールドが含まれています。出力オプションは、各出力ドキュメントに含まれるフィールドを指定します。

$bucket は、1 つ以上の入力ドキュメントを含むバケットでのみ出力ドキュメントを生成します。

$bucketステージには100メガバイトの RAM 制限があります。 デフォルトでは、 ステージがこの制限を超えると、 $bucketはエラーを返します。 ステージ処理に使用できるスペースを増やすには、 allowDiskUseオプションを使用して集計パイプライン ステージで一時ファイルにデータを書込みます。

Tip

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

{
$bucket: {
groupBy: <expression>,
boundaries: [ <lowerbound1>, <lowerbound2>, ... ],
default: <literal>,
output: {
<output1>: { <$accumulator expression> },
...
<outputN>: { <$accumulator expression> }
}
}
}

$bucketドキュメントには次のフィールドが含まれています。

フィールド
タイプ
説明

ドキュメントをグループ化するための式。フィールドパスを指定するには、フィールド名の前にドル記号($)を付け、引用符で囲みます。

$bucketにデフォルト指定が含まれていない限り、各入力ドキュメントはgroupBy フィールドパスまたは式を、境界で指定された範囲に含まれる値に変換する必要があります。

配列

各バケットの境界を指定する groupBy式に基づく値の配列。隣接する各値のペアは、バケットの包括的な下限と排他的な上限として機能します。少なくとも 2 つの境界を指定する必要があります。

指定する値は昇順で、すべて同じである必要があります。ただし、値が次のような混合数値型である場合を除きます。

[ 10, NumberLong(20), NumberInt(30) ]

例、[ 0, 5, 10 ] の配列によって次の 2 つのバケットが作成されます。

  • [0, 5) は下限 0 を包含し、上限 5 を除外します。

  • [5, 10) は下限 5 を包含し、上限 10 を除外します。

literal

任意。_id groupBy式の結果が境界で指定されたバケットに該当しないすべてのドキュメントを含む追加のバケットの を指定するリテラル。

指定しない場合、各入力ドキュメントは groupBy 式を boundaries で指定されたいずれかのバケット範囲内の値に変換する必要があります。

default 値は、boundaries の下限未満か、boundaries の上限以上である必要があります。

default 値は boundaries のエントリと タイプが異なることもあります。

ドキュメント

省略可能。_id フィールド以外で出力ドキュメントに含めるフィールドを指定するドキュメント。含めるフィールドを指定するには、アキュムレータ式を使用する必要があります。

<outputfield1>: { <accumulator>: <expression1> },
...
<outputfieldN>: { <accumulator>: <expressionN> }

output ドキュメントを指定しない場合、操作により各バケット内のドキュメント数を含む count フィールドが返されます。

output ドキュメントを指定すると、このドキュメントの指定フィールドのみが返されます。つまり、count フィールドは、output ドキュメントに明示的に含まれていない限り返されません。

$bucket では以下の条件の 1 つ以上が満たされる必要があります。そうでない場合、操作でエラーがスローされます。

  • 各入力ドキュメントは、groupBy 式を、境界で指定されたバケット範囲内のいずれかの値に変換します。または

  • デフォルト値は、 groupBy値がboundariesの外部であるか、 boundariesの値と異なるBSON タイプであるドキュメントをバケット化するために指定されます。

groupBy 式が配列またはドキュメントに変換される場合、$bucket$sort の比較ロジックを使用して入力ドキュメントをバケットに配置します。

mongoshでは、次のドキュメントを含むartistsという名前のサンプル コレクションが作成されます。

db.artists.insertMany([
{ "_id" : 1, "last_name" : "Bernard", "first_name" : "Emil", "year_born" : 1868, "year_died" : 1941, "nationality" : "France" },
{ "_id" : 2, "last_name" : "Rippl-Ronai", "first_name" : "Joszef", "year_born" : 1861, "year_died" : 1927, "nationality" : "Hungary" },
{ "_id" : 3, "last_name" : "Ostroumova", "first_name" : "Anna", "year_born" : 1871, "year_died" : 1955, "nationality" : "Russia" },
{ "_id" : 4, "last_name" : "Van Gogh", "first_name" : "Vincent", "year_born" : 1853, "year_died" : 1890, "nationality" : "Holland" },
{ "_id" : 5, "last_name" : "Maurer", "first_name" : "Alfred", "year_born" : 1868, "year_died" : 1932, "nationality" : "USA" },
{ "_id" : 6, "last_name" : "Munch", "first_name" : "Edvard", "year_born" : 1863, "year_died" : 1944, "nationality" : "Norway" },
{ "_id" : 7, "last_name" : "Redon", "first_name" : "Odilon", "year_born" : 1840, "year_died" : 1916, "nationality" : "France" },
{ "_id" : 8, "last_name" : "Diriks", "first_name" : "Edvard", "year_born" : 1855, "year_died" : 1930, "nationality" : "Norway" }
])

次の操作では、year_born フィールドに従ってドキュメントをバケットにグループ化し、バケット内のドキュメント数に基づいてフィルタリングします。

db.artists.aggregate( [
// First Stage
{
$bucket: {
groupBy: "$year_born", // Field to group by
boundaries: [ 1840, 1850, 1860, 1870, 1880 ], // Boundaries for the buckets
default: "Other", // Bucket ID for documents which do not fall into a bucket
output: { // Output for each bucket
"count": { $sum: 1 },
"artists" :
{
$push: {
"name": { $concat: [ "$first_name", " ", "$last_name"] },
"year_born": "$year_born"
}
}
}
}
},
// Second Stage
{
$match: { count: {$gt: 3} }
}
] )
第 1 ステージ

$bucketステージでは、ドキュメントはyear_bornフィールドでバケットにグループ化されます。 バケットには次の境界があります。

  • [1840, 1850) は下限 1840 を包含し、上限 1850 を除外します。

  • [1850, 1860) は、下限 1850 を包含し、上限 1860 を除外します。

  • [1860, 1870) は、下限 1860 を包含し、上限 1870 を除外します。

  • [1870, 1880) は、下限 1870 を包含し、上限 1880 を除外します。

  • ドキュメントにyear_bornフィールドが含まれていない場合、またはそのyear_bornフィールドが上記の範囲外の場合、そのドキュメントは_id"Other"を持つデフォルトのバケットに配置されます。

このステージには、返すフィールドを決定するための出力ドキュメントが含まれます。

フィールド
説明

_id

バケットの下限を含みます。

count

バケット内のドキュメント数。

artists

バケット内の各アーティストに関する情報が記載されているドキュメントの配列。各ドキュメントにはアーティストに関する次の情報が記載されています。

  • name は、アーティストのfirst_namelast_name の連結($concat)を含みます。

  • year_born

このステージでは、次のドキュメントを次のステージに渡します。

{ "_id" : 1840, "count" : 1, "artists" : [ { "name" : "Odilon Redon", "year_born" : 1840 } ] }
{ "_id" : 1850, "count" : 2, "artists" : [ { "name" : "Vincent Van Gogh", "year_born" : 1853 },
{ "name" : "Edvard Diriks", "year_born" : 1855 } ] }
{ "_id" : 1860, "count" : 4, "artists" : [ { "name" : "Emil Bernard", "year_born" : 1868 },
{ "name" : "Joszef Rippl-Ronai", "year_born" : 1861 },
{ "name" : "Alfred Maurer", "year_born" : 1868 },
{ "name" : "Edvard Munch", "year_born" : 1863 } ] }
{ "_id" : 1870, "count" : 1, "artists" : [ { "name" : "Anna Ostroumova", "year_born" : 1871 } ] }
第 2 ステージ

$match ステージでは、前のステージからの出力をフィルタリングして、3 つ以上のドキュメントを含むバケットのみが返されます。

この操作を実行すると次のドキュメントが返されます。

{ "_id" : 1860, "count" : 4, "artists" :
[
{ "name" : "Emil Bernard", "year_born" : 1868 },
{ "name" : "Joszef Rippl-Ronai", "year_born" : 1861 },
{ "name" : "Alfred Maurer", "year_born" : 1868 },
{ "name" : "Edvard Munch", "year_born" : 1863 }
]
}

$facetステージを使用して、1 つのステージで複数の$bucket集計を実行できます。

mongoshでは、次のドキュメントを含むartworkという名前のサンプル コレクションが作成されます。

db.artwork.insertMany([
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926,
"price" : NumberDecimal("199.99") },
{ "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902,
"price" : NumberDecimal("280.00") },
{ "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925,
"price" : NumberDecimal("76.04") },
{ "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai",
"price" : NumberDecimal("167.30") },
{ "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931,
"price" : NumberDecimal("483.00") },
{ "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913,
"price" : NumberDecimal("385.00") },
{ "_id" : 7, "title" : "The Scream", "artist" : "Munch", "year" : 1893
/* No price*/ },
{ "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918,
"price" : NumberDecimal("118.42") }
])

次の操作では、$facet ステージ内の 2 つの $bucket ステージを使用して 2 つのグループが作成されます。1 つは price 別のグループ、もう 1 つは year 別のグループです。

db.artwork.aggregate( [
{
$facet: { // Top-level $facet stage
"price": [ // Output field 1
{
$bucket: {
groupBy: "$price", // Field to group by
boundaries: [ 0, 200, 400 ], // Boundaries for the buckets
default: "Other", // Bucket ID for documents which do not fall into a bucket
output: { // Output for each bucket
"count": { $sum: 1 },
"artwork" : { $push: { "title": "$title", "price": "$price" } },
"averagePrice": { $avg: "$price" }
}
}
}
],
"year": [ // Output field 2
{
$bucket: {
groupBy: "$year", // Field to group by
boundaries: [ 1890, 1910, 1920, 1940 ], // Boundaries for the buckets
default: "Unknown", // Bucket ID for documents which do not fall into a bucket
output: { // Output for each bucket
"count": { $sum: 1 },
"artwork": { $push: { "title": "$title", "year": "$year" } }
}
}
}
]
}
}
] )
最初のファセット

最初のファセットは、入力ドキュメントを price でグループ化します。バケットには次の境界があります。

  • [0, 200) は下限 0 を包含し、上限 200 を除外します。

  • [200, 400) は下限 200 を包含し、上限 400 を除外します。

  • 「その他」は default バケットで、価格がないか、上記の範囲外の価格のドキュメントを含みます。

$bucket ステージには、返されるフィールドを決定するための出力ドキュメントが含まれます。

フィールド
説明

_id

バケットの下限を含みます。

count

バケット内のドキュメント数。

artwork

バケット内の各アート作品に関する情報を含むドキュメントの配列。

averagePrice

$avg演算子を使用して、バケット内のすべてのアート作品の平均価格を表示します。

2 番目のファセット

2 番目のファセットでは、入力ドキュメントを year でグループ化します。バケットには次の境界があります。

  • [1890、1910) は、下限 1890 を包含し、上限 1910 を除外します。

  • [1910, 1920) は、下限 1910 を包含し、上限 1920 を除外します。

  • [1920, 1940) は、下限 1910 を包含し、上限 1940 を除外します。

  • 「不明」は default バケットで、年数がないか、上記の範囲外の年数であるドキュメントを含みます。

$bucket ステージには、返されるフィールドを決定するための出力ドキュメントが含まれます。

フィールド
説明

count

バケット内のドキュメント数。

artwork

バケット内の各アート作品に関する情報を含むドキュメントの配列。

出力

この操作を実行すると次のドキュメントが返されます。

{
"price" : [ // Output of first facet
{
"_id" : 0,
"count" : 4,
"artwork" : [
{ "title" : "The Pillars of Society", "price" : NumberDecimal("199.99") },
{ "title" : "Dancer", "price" : NumberDecimal("76.04") },
{ "title" : "The Great Wave off Kanagawa", "price" : NumberDecimal("167.30") },
{ "title" : "Blue Flower", "price" : NumberDecimal("118.42") }
],
"averagePrice" : NumberDecimal("140.4375")
},
{
"_id" : 200,
"count" : 2,
"artwork" : [
{ "title" : "Melancholy III", "price" : NumberDecimal("280.00") },
{ "title" : "Composition VII", "price" : NumberDecimal("385.00") }
],
"averagePrice" : NumberDecimal("332.50")
},
{
// Includes documents without prices and prices greater than 400
"_id" : "Other",
"count" : 2,
"artwork" : [
{ "title" : "The Persistence of Memory", "price" : NumberDecimal("483.00") },
{ "title" : "The Scream" }
],
"averagePrice" : NumberDecimal("483.00")
}
],
"year" : [ // Output of second facet
{
"_id" : 1890,
"count" : 2,
"artwork" : [
{ "title" : "Melancholy III", "year" : 1902 },
{ "title" : "The Scream", "year" : 1893 }
]
},
{
"_id" : 1910,
"count" : 2,
"artwork" : [
{ "title" : "Composition VII", "year" : 1913 },
{ "title" : "Blue Flower", "year" : 1918 }
]
},
{
"_id" : 1920,
"count" : 3,
"artwork" : [
{ "title" : "The Pillars of Society", "year" : 1926 },
{ "title" : "Dancer", "year" : 1925 },
{ "title" : "The Persistence of Memory", "year" : 1931 }
]
},
{
// Includes documents without a year
"_id" : "Unknown",
"count" : 1,
"artwork" : [
{ "title" : "The Great Wave off Kanagawa" }
]
}
]
}

Tip

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

戻る

$addFields