定義
$bucketAuto指定された式に基づいて、受信したドキュメントをバケットと呼ばれる特定の数のグループに分類します。指定された数のバケットにドキュメントを均等に分散するために、バケット境界が自動的に決定されます。
各バケットは、出力ではドキュメントとして表されます。 各バケットのドキュメントには、次の内容が含まれています。
バケットの境界を指定する
_idオブジェクト。_id.minフィールドは、バケットの包括的下限を指定します。_id.maxフィールドはバケットの上限を指定します。 この限界は、シリーズの最後のバケットを 除く すべてのバケットに対して排他的です。ここでは包括的です。
バケット内のドキュメント数を含む
countフィールド。outputドキュメントが指定されていない場合、countフィールドはデフォルトで含まれます。
The
$bucketAutostage has the following form:{ $bucketAuto: { groupBy: <expression>, buckets: <number>, output: { <output1>: { <$accumulator expression> }, ... } granularity: <string> } } フィールドタイプ説明groupBy式
bucketsinteger
入力ドキュメントがグループ化されるバケット数を指定する正の 32 ビット整数。
outputドキュメント
任意。
_idフィールド以外で出力ドキュメントに含めるフィールドを指定するドキュメント。 含めるフィールドを指定するには、アキュムレータ式を使用する必要があります。<outputfield1>: { <accumulator>: <expression1> }, ... outputが指定されている場合、デフォルトのcountフィールドは出力ドキュメントに含まれません。 次のとおり、outputドキュメントの一部としてcount式を明示的に指定して含めます。output: { <outputfield1>: { <accumulator>: <expression1> }, ... count: { $sum: 1 } } granularitystring
Considerations
$bucketAuto およびメモリ制限
$bucketAutoステージには100 メガバイトのRAM制限があります。デフォルトでは 、 ステージがこの制限を超えると、 MongoDB は一時ファイルを自動的にディスクに書込みます。詳細については、 を参照してください。allowDiskUseByDefault
Tip
動作
次の場合には、指定されたバケット数を下回る可能性があります。
入力ドキュメント数が指定されたバケット数より小さいです。
groupBy式の一意の値の数は、bucketsの指定された数より小さいです。granularityの間隔はbucketsの数より少ないです。granularityは、指定された数のbucketsにドキュメントを均等に分散するのに十分ではありません。
groupBy式が配列またはドキュメントを参照する場合、バケット境界を決定する前に、 $sortと同じ順序で値が配置されます。
バケット間でのドキュメントの均等な分散は、 groupByフィールドの濃度または一意の値の数によって異なります。 濃度が十分に高くない場合、$bucketAuto ステージは結果をバケット間で均等に分散しない可能性があります。
粒度
The $bucketAuto accepts an optional granularity parameter which ensures that the boundaries of all buckets adhere to a specified preferred number series. Using a preferred number series provides more control on where the bucket boundaries are set among the range of values in the groupBy expression. They may also be used to help logarithmically and evenly set bucket boundaries when the range of the groupBy expression scales exponentially.
シャード シリーズ
レナード数値系列は、5番目の 、10番目の 、20番目の 、40番目の 、または 10 のルートのいずれかを取得して得られる数値のセットであり、1.0 から 10.0 までの値に等しいルートの累乗を含みます(10.3 では 10.3 ( R80の場合)。
バケット境界を系列内の値に制限するには、 granularityをR5 、 R10 、 R20 、 R40 、またはR80に設定します。 groupByの値が 1.0 から 10.0( R80では 10.3)の範囲外の場合、系列の値は 10 の累乗を掛けます。
例
R5系列は 10 の 5 のルート(1.58)に基づいており、10 に達するまでこのルートのさまざまな累乗(丸め)が含まれます。 R5シリーズは次のように派生します。
10 0/5 = 1
10 1/5 = 1.584 ~ 1.6
10 2/5 = 2.511 ~ 2.5
10 3/5 = 3.981 ~ 4.0
10 4/5 = 6.309 ~ 6.3
10 5/5 = 10
より細かい粒度、つまり 1.0 から 10.0( R80では 10.3)の間隔が長くなります。
E シリーズ
E 番号系列は 1、.0 10から.0 までの間隔を6 th、12 th、 th、 24th、 48th、または 96と192 10 のルートで特定の相対エラーが発生します。
バケット境界を系列内の値に制限するには、 granularityをE6 、 E12 、 E24 、 E48 、 E96 、またはE192に設定します。 シリーズの値は、 groupByの値が1の範囲外の場合、 10の累乗を掛けます。 0から10 。 0の範囲 E シリーズ とそれぞれの相対的なエラーの詳細については、次を参照してください。 。
1-2-5 シリーズ
1-2-5シリーズは、 3 値のRapid シリーズのように動作します(このようなシリーズが存在する場合)。
granularityを1-2-5に設定すると、バケット境界を 10 の 3 ルート(1 桁に丸められた)のさまざまな累乗に制限します。
例
次の値は1-2-5シリーズの一部です。0.1、0.2、0.5、1、2、5、10、20、50、100、200、500、1000、など
2 つの系列の累乗
バケット境界を 2 の累乗の数値に制限するには、 granularityをPOWERSOF2に設定します。
例
次の数値は 2 つの系列の累乗に依存します。
2 0 = 1
2 1 = 2
2 2 = 4
2 3 = 8
2 4 = 16
2 5 = 32
などです。
一般的な実装は、メモリなどのさまざまなコンピューター コンポーネントがPOWERSOF2の優先番号のセットに頻繁に結合される方法を示しています。
1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, and so on....
異なる粒度の比較
次の操作は、 granularityに別の値を指定することが、 $bucketAutoのバケット境界の決定方法に影響することを示しています。 thingsのコレクションには、0 から 99 までの番号付けされた_idがあります。
{ _id: 0 } { _id: 1 } ... { _id: 99 }
granularityの異なる値は次の操作に置き換えられます。
db.things.aggregate( [ { $bucketAuto: { groupBy: "$_id", buckets: 5, granularity: <granularity> } } ] )
次の表の結果は、 granularityの異なる値によってどのように異なるバケット境界が生成されるかを示しています。
粒度 | 結果 | ノート |
|---|---|---|
粒度なし | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } | |
R20 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } | |
E24 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } | |
1-2-5 | { "_id" : { "min" : 0, "max" : 20 }, "count" : 20 } | 指定されたバケット数がシリーズ内の間隔数を超えています。 |
POWERSOF2 | { "_id" : { "min" : 0, "max" : 32 }, "count" : 32 } | 指定されたバケット数がシリーズ内の間隔数を超えています。 |
例
以下のドキュメントを持つ artwork コレクションを考えてみましょう。
{ "_id" : 1, "title" : "The Pillars of Society", "artist" : "Grosz", "year" : 1926, "price" : Decimal128("199.99"), "dimensions" : { "height" : 39, "width" : 21, "units" : "in" } } { "_id" : 2, "title" : "Melancholy III", "artist" : "Munch", "year" : 1902, "price" : Decimal128("280.00"), "dimensions" : { "height" : 49, "width" : 32, "units" : "in" } } { "_id" : 3, "title" : "Dancer", "artist" : "Miro", "year" : 1925, "price" : Decimal128("76.04"), "dimensions" : { "height" : 25, "width" : 20, "units" : "in" } } { "_id" : 4, "title" : "The Great Wave off Kanagawa", "artist" : "Hokusai", "price" : Decimal128("167.30"), "dimensions" : { "height" : 24, "width" : 36, "units" : "in" } } { "_id" : 5, "title" : "The Persistence of Memory", "artist" : "Dali", "year" : 1931, "price" : Decimal128("483.00"), "dimensions" : { "height" : 20, "width" : 24, "units" : "in" } } { "_id" : 6, "title" : "Composition VII", "artist" : "Kandinsky", "year" : 1913, "price" : Decimal128("385.00"), "dimensions" : { "height" : 30, "width" : 46, "units" : "in" } } { "_id" : 7, "title" : "The Scream", "artist" : "Munch", "price" : Decimal128("159.00"), "dimensions" : { "height" : 24, "width" : 18, "units" : "in" } } { "_id" : 8, "title" : "Blue Flower", "artist" : "O'Keefe", "year" : 1918, "price" : Decimal128("118.42"), "dimensions" : { "height" : 24, "width" : 20, "units" : "in" } }
単一ファセット集計
次の操作では、入力ドキュメントは、 priceフィールドの値に従って 4 つのバケットにグループ化されます。
db.artwork.aggregate( [ { $bucketAuto: { groupBy: "$price", buckets: 4 } } ] )
この操作により、次のドキュメントが返されます。
{ "_id" : { "min" : Decimal128("76.04"), "max" : Decimal128("159.00") }, "count" : 2 } { "_id" : { "min" : Decimal128("159.00"), "max" : Decimal128("199.99") }, "count" : 2 } { "_id" : { "min" : Decimal128("199.99"), "max" : Decimal128("385.00") }, "count" : 2 } { "_id" : { "min" : Decimal128("385.00"), "max" : Decimal128("483.00") }, "count" : 2 }
ファセット集計
The $bucketAuto stage can be used within the $facet stage to process multiple aggregation pipelines on the same set of input documents from artwork.
次の集計パイプラインでは、 artworkコレクションのドキュメントを、 price 、 year 、および計算されたareaに基づいてバケットにグループ化します。
db.artwork.aggregate( [ { $facet: { "price": [ { $bucketAuto: { groupBy: "$price", buckets: 4 } } ], "year": [ { $bucketAuto: { groupBy: "$year", buckets: 3, output: { "count": { $sum: 1 }, "years": { $push: "$year" } } } } ], "area": [ { $bucketAuto: { groupBy: { $multiply: [ "$dimensions.height", "$dimensions.width" ] }, buckets: 4, output: { "count": { $sum: 1 }, "titles": { $push: "$title" } } } } ] } } ] )
この操作を実行すると次のドキュメントが返されます。
{ "area" : [ { "_id" : { "min" : 432, "max" : 500 }, "count" : 3, "titles" : [ "The Scream", "The Persistence of Memory", "Blue Flower" ] }, { "_id" : { "min" : 500, "max" : 864 }, "count" : 2, "titles" : [ "Dancer", "The Pillars of Society" ] }, { "_id" : { "min" : 864, "max" : 1568 }, "count" : 2, "titles" : [ "The Great Wave off Kanagawa", "Composition VII" ] }, { "_id" : { "min" : 1568, "max" : 1568 }, "count" : 1, "titles" : [ "Melancholy III" ] } ], "price" : [ { "_id" : { "min" : Decimal128("76.04"), "max" : Decimal128("159.00") }, "count" : 2 }, { "_id" : { "min" : Decimal128("159.00"), "max" : Decimal128("199.99") }, "count" : 2 }, { "_id" : { "min" : Decimal128("199.99"), "max" : Decimal128("385.00") }, "count" : 2 }, { "_id" : { "min" : Decimal128("385.00"), "max" : Decimal128("483.00") }, "count" : 2 } ], "year" : [ { "_id" : { "min" : null, "max" : 1913 }, "count" : 3, "years" : [ 1902 ] }, { "_id" : { "min" : 1913, "max" : 1926 }, "count" : 3, "years" : [ 1913, 1918, 1925 ] }, { "_id" : { "min" : 1926, "max" : 1931 }, "count" : 2, "years" : [ 1926, 1931 ] } ] }
このページの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; } [] 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 $bucketAuto stage to an aggregation pipeline, call the Unwind() method on a PipelineDefinition object.
次の例では、Runtimeフィールドの値でドキュメントを 5 つのバケットに均等に分散するパイプラインステージを作成します。
var pipeline = new EmptyPipelineDefinition<Movie>() .BucketAuto( groupBy: m => m.Runtime, buckets: 5);
AggregateBbucketAutoOptionsオブジェクトを使用して、境界値を設定するための数値ベースのスキームを指定できます。次の例では、前の例と同じ $bucketAuto操作を実行しますが、 の累乗にバケット境界を設定します。2
var bucketAutoOptions = new AggregateBucketAutoOptions() { Granularity = new AggregateBucketAutoGranularity("POWERSOF2") }; var pipeline = new EmptyPipelineDefinition<Movie>() .BucketAuto( groupBy: m => m.Runtime, buckets: 5, options: bucketAutoOptions);
このページのNode.js の例では、Atlasサンプルデータセット の sample_mflixデータベースを使用します。無料のMongoDB Atlas cluster を作成し、サンプルデータセットをロードする方法については、 MongoDB Node.jsドライバーのドキュメントの開始を参照してください。
MongoDB Node.jsドライバーを使用して $bucketAuto ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $bucketAuto 演算子を使用します。
次の例では、runtimeフィールドの値でドキュメントを 5 つのバケットに均等に分散するパイプラインステージを作成しています。次に、この例では集計パイプラインを実行します。
const pipeline = [ { $bucketAuto: { groupBy: "$runtime", buckets: 5 } } ]; const cursor = collection.aggregate(pipeline); return cursor;
次の例では、前の例と同じ $bucketAuto操作を実行しますが、granularity パラメータを使用してバケット境界を 2 の累乗として設定します。
const pipeline = [ { $bucketAuto: { groupBy: "$runtime", buckets: 5, granularity: "POWERSOF2" } } ]; const cursor = collection.aggregate(pipeline); return cursor;
詳細
関連するパイプラインステージの詳細については、$bucketガイドを参照してください。