AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

$バケット(集計ステージ)

$bucket

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

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

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

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

The $bucket document contains the following fields:

フィールド
タイプ
説明

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

Unless $bucket includes a default specification, each input document must resolve the groupBy field path or expression to a value that falls within one of the ranges specified by the boundaries.

配列

An array of values based on the groupBy expression that specify the boundaries for each bucket. Each adjacent pair of values acts as the inclusive lower boundary and the exclusive upper boundary for the bucket. You must specify at least two boundaries.

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

[ 10, Long(20), Int32(30) ]

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

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

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

literal

Optional. A literal that specifies the _id of an additional bucket that contains all documents whose groupBy expression result does not fall into a bucket specified by boundaries.

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

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

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

ドキュメント

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

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

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

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

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

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

  • A default value is specified to bucket documents whose groupBy values are outside of the boundaries or of a different BSON type than the values in boundaries.

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

In mongosh, create a sample collection named artists with the following documents:

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 ステージ

The $bucket stage groups the documents into buckets by the year_born field. The buckets have the following boundaries:

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

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

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

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

  • If a document did not contain the year_born field or its year_born field was outside the ranges above, it would be placed in the default bucket with the _id value "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 }
]
}

You can use the $facet stage to perform multiple $bucket aggregations in a single stage.

In mongosh, create a sample collection named artwork with the following documents:

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

The following operation uses two $bucket stages within a $facet stage to create two groupings, one by price and the other by 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 バケットで、価格がないか、上記の範囲外の価格のドキュメントを含みます。

The $bucket stage includes the output document to determine the fields to return:

フィールド
説明

_id

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

count

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

artwork

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

averagePrice

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

2 番目のファセット

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

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

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

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

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

The $bucket stage includes the output document to determine the fields to return:

フィールド
説明

count

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

artwork

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

出力

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

{
"price" : [ // Output of first facet
{
"_id" : 0,
"count" : 4,
"artwork" : [
{ "title" : "The Pillars of Society", "price" : Decimal128("199.99") },
{ "title" : "Dancer", "price" : Decimal128("76.04") },
{ "title" : "The Great Wave off Kanagawa", "price" : Decimal128("167.30") },
{ "title" : "Blue Flower", "price" : Decimal128("118.42") }
],
"averagePrice" : Decimal128("140.4375")
},
{
"_id" : 200,
"count" : 2,
"artwork" : [
{ "title" : "Melancholy III", "price" : Decimal128("280.00") },
{ "title" : "Composition VII", "price" : Decimal128("385.00") }
],
"averagePrice" : Decimal128("332.50")
},
{
// Includes documents without prices and prices greater than 400
"_id" : "Other",
"count" : 2,
"artwork" : [
{ "title" : "The Persistence of Memory", "price" : Decimal128("483.00") },
{ "title" : "The Scream" }
],
"averagePrice" : Decimal128("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" }
]
}
]
}

このページのC#の例では、Atlasサンプルデータセットsample_mflixデータベースを使用します。MongoDB Atlasクラスターを無料で作成して、サンプルデータセットをロードする方法については、 MongoDB .NET/ C#ドライバーのドキュメントの「 開始 」を参照してください。

次の Movie クラスは、sample_mflix.movies コレクション内のドキュメントをモデル化します。

public class Movie
{
public ObjectId Id { get; set; }
public int Runtime { get; set; }
public string Title { get; set; }
public string Rated { get; set; }
public List<string> Genres { get; set; }
public string Plot { get; set; }
public ImdbData Imdb { get; set; }
public int Year { get; set; }
public int Index { get; set; }
public string[] Comments { get; set; }
[BsonElement("lastupdated")]
public DateTime LastUpdated { get; set; }
}

注意

パスカルケースの ConventionPack

このページのC# クラスはプロパティ名にパスカルケースを使用していますが、MongoDB コレクションのフィールド名はキャメルケースを使用しています。この違いを考慮するために、アプリケーションが起動する際に次のコードを使用してConventionPackを登録してください。

var camelCaseConvention = new ConventionPack { new CamelCaseElementNameConvention() };
ConventionRegistry.Register("CamelCase", camelCaseConvention, type => true);

To use the MongoDB .NET/C# driver to add a $bucket stage to an aggregation pipeline, call the Unwind() method on a PipelineDefinition object.

次の例では、受信ドキュメントを Runtimeフィールドの値でグループ化するパイプラインステージを作成します。これは下限を含み、上限を含まない値です。

var pipeline = new EmptyPipelineDefinition<Movie>()
.Bucket(
groupBy: m => m.Runtime,
boundaries: new List<int>() { 0, 71, 91, 121, 151, 201, 999 });

To customize the $bucket operation, pass an AggregateBucketOptions object to the Bucket() method. The following example performs the same $bucket operation as the previous example, but groups all documents with a Runtime value greater than 999 into the default bucket, named "Other":

var bucketOptions = new AggregateBucketOptions<BsonValue>()
{
DefaultBucket = (BsonValue)"Other"
};
var pipeline = new EmptyPipelineDefinition<Movie>()
.Bucket(
groupBy: m => m.Runtime,
boundaries: new List<BsonValue>() { 0, 71, 91, 121, 151, 201, 999 },
options: bucketOptions);

このページのNode.js の例では、Atlasサンプルデータセットsample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。

MongoDB Node.jsドライバーを使用して $bucket ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $bucket 演算子を使用します。

次の例では、下限を含み上限を除いた runtime フィールドの値で受信するドキュメントをグループ化するパイプラインステージを作成します。集計ステージは、runtime の値が 999 を超えるすべてのドキュメントを "other" という名前のデフォルトのバケットにグループ化します。次に、この例は集計パイプラインを実行します。

const pipeline = [
{
$bucket: {
groupBy: "$runtime",
boundaries: [0, 17, 91, 121, 151, 201, 999],
default: "other"
}
}
];
const cursor = collection.aggregate(pipeline);
return cursor;

関連するパイプラインステージの詳細については、$bucketAutoガイドを参照してください。