Aggregation Pipeline
集計パイプラインは、ドキュメントを処理する 1 つ以上の ステージで構成されます。
各ステージは、入力ドキュメントに対して操作を実行します。 例えば、ステージでは、文書のフィルター処理、文書のグループ化、および値の計算を行うことができます。
ステージから出力された文書は、次のステージに渡されます。
aggregation pipelineドキュメントのグループの結果を返すことができます。 たとえば、合計値、平均値、最大値、最小値を返します。
aggregation pipeline aggregation pipelineでドキュメントを更新できます。
注意
db.collection.aggregate()
メソッドで実行される集計パイプラインは、パイプラインに $merge
または $out
ステージが含まれていない限り、コレクション内のドキュメントを変更しません。
MongoDB Atlasでホストされている配置の UI で集計パイプラインを実行できます。
MongoDB Atlas UI で MongoDB Atlas 配置に対して集計パイプラインを実行すると、各ステージで結果をプレビューできます。
完全な集計パイプラインの例
このセクションでは、次のピザ orders
コレクションを使用する集計パイプラインを例示します。
db.orders.insertMany( [ { _id: 0, name: "Pepperoni", size: "small", price: 19, quantity: 10, date: ISODate( "2021-03-13T08:14:30Z" ) }, { _id: 1, name: "Pepperoni", size: "medium", price: 20, quantity: 20, date : ISODate( "2021-03-13T09:13:24Z" ) }, { _id: 2, name: "Pepperoni", size: "large", price: 21, quantity: 30, date : ISODate( "2021-03-17T09:22:12Z" ) }, { _id: 3, name: "Cheese", size: "small", price: 12, quantity: 15, date : ISODate( "2021-03-13T11:21:39.736Z" ) }, { _id: 4, name: "Cheese", size: "medium", price: 13, quantity:50, date : ISODate( "2022-01-12T21:23:13.331Z" ) }, { _id: 5, name: "Cheese", size: "large", price: 14, quantity: 10, date : ISODate( "2022-01-12T05:08:13Z" ) }, { _id: 6, name: "Vegan", size: "small", price: 17, quantity: 10, date : ISODate( "2021-01-13T05:08:13Z" ) }, { _id: 7, name: "Vegan", size: "medium", price: 18, quantity: 10, date : ISODate( "2021-01-13T05:10:13Z" ) } ] )
合計注文数の計算
次の集計パイプラインの例には 2 つのステージが含まれており、ピザ名ごとにグループ化された中サイズのピザの合計注文数量を返します。
db.orders.aggregate( [ // Stage 1: Filter pizza order documents by pizza size { $match: { size: "medium" } }, // Stage 2: Group remaining documents by pizza name and calculate total quantity { $group: { _id: "$name", totalQuantity: { $sum: "$quantity" } } } ] )
$match
段階:
ピザ注文ドキュメントを、
medium
のsize
を持つピザにフィルタリングします。残りのドキュメントを
$group
ステージに渡します。
$group
段階:
残りのドキュメントをピザ
name
でグループ化します。$sum
を使用して、各ピザname
の合計注文quantity
を計算します。合計は、 aggregation pipelineによって返されるtotalQuantity
フィールドに格納されます。
出力例:
[ { _id: 'Cheese', totalQuantity: 50 }, { _id: 'Vegan', totalQuantity: 10 }, { _id: 'Pepperoni', totalQuantity: 20 } ]
合計注文額と平均注文数の計算
次の例では、2 日間にまたがるピザの合計注文額と平均注文数を計算しています。
db.orders.aggregate( [ // Stage 1: Filter pizza order documents by date range { $match: { "date": { $gte: new ISODate( "2020-01-30" ), $lt: new ISODate( "2022-01-30" ) } } }, // Stage 2: Group remaining documents by date and calculate results { $group: { _id: { $dateToString: { format: "%Y-%m-%d", date: "$date" } }, totalOrderValue: { $sum: { $multiply: [ "$price", "$quantity" ] } }, averageOrderQuantity: { $avg: "$quantity" } } }, // Stage 3: Sort documents by totalOrderValue in descending order { $sort: { totalOrderValue: -1 } } ] )
$match
段階:
$group
段階:
$dateToString
を使用して、ドキュメントを日付別にグループ化します。グループごとに、次の計算を行います。
グループ化されたドキュメントを
$sort
ステージに渡します。
$sort
段階:
各グループの合計注文額でドキュメントを降順(
-1
)でソートします。ソートされたドキュメントを返します。
出力例:
[ { _id: '2022-01-12', totalOrderValue: 790, averageOrderQuantity: 30 }, { _id: '2021-03-13', totalOrderValue: 770, averageOrderQuantity: 15 }, { _id: '2021-03-17', totalOrderValue: 630, averageOrderQuantity: 30 }, { _id: '2021-01-13', totalOrderValue: 350, averageOrderQuantity: 10 } ]
追加の集計パイプライン ステージの詳細
aggregation pipeline 、ドキュメントを処理する 1 つ以上のステージで構成されます。
ステージでは、入力ドキュメントごとに 1 つのドキュメントを出力する必要はありません。たとえば、一部のステージでは、新しいドキュメントを作成したり、フィルターでドキュメントを除外したりする場合があります。
$out
、$merge
、$geoNear
ステージを除き、同じステージがパイプラインに何度か表示される可能性があります。ステージ内で平均を計算したり、その他の計算を実行するには、集計演算子を指定する集計式を使用します。集計式については、次のセクションで詳しく説明します。
すべての集計ステージについては、「集計ステージ」を参照してください。
集計式と演算子
一部の集計パイプライン ステージは式を受け入れます。 演算子は入力式に基づいて値を計算します。
MongoDB クエリ言語では、次のコンポーネントから式を構築できます。
コンポーネント | 例 |
---|---|
定数 | 3 |
演算子 | |
フィールドパス式 | "$<path.to.field>" |
たとえば、 { $add: [ 3, "$inventory.total" ] }
は$add
演算子と 2 つの入力式で構成される式です。
定数
3
フィールドパス式
"$inventory.total"
式は、入力ドキュメントのパスinventory.total
の値に3を追加した結果を返します。
フィールドパス
フィールドパス式は、入力ドキュメント内のフィールドにアクセスするために使用されます。 フィールドパスを指定するには、フィールド名またはドット付きフィールド名(埋め込みドキュメント内のフィールドの場合)の前にドル記号$
を付けます。 たとえば、 "$user"
はuser
フィールドのフィールドパスを指定し、 "$user.name"
は埋め込み"user.name"
フィールドへのフィールドパスを指定します。
"$<field>"
は "$$CURRENT.<field>"
と同等であり、CURRENT
は、特定のステージで別途明示される場合を除き、現在のオブジェクトのルートにデフォルト設定されるシステム変数です。
集計パイプラインの実行
集計パイプラインを実行するには、以下を使用します。
集計パイプラインを使用したドキュメントの更新
集計パイプラインでドキュメントを更新するには、以下を使用します。
その他の考慮事項
集計パイプラインの制限
集計パイプラインでは、値の型と結果のサイズに制限があります。詳細については、「集計パイプラインの制限」を参照してください。
集計パイプラインとシャーディングされたコレクション
集計パイプラインでは、シャーディングされたコレクションに対して操作を実行できます。詳細については、「集計パイプラインとシャーディングされたコレクション」を参照してください。
map-reduce の代替としての集計パイプライン
MongoDB 5.0 以降、map-reduce は非推奨になっています。
map-reduce の代わりに、集計パイプラインを使用してください。集計パイプラインは、map-reduce よりもパフォーマンスとユーザビリティが優れています。
map-reduce 操作は、
$group
、$merge
などの集計パイプライン ステージ を使用して書き換えることができます。カスタム機能を必要とする map-reduce 操作には、
$accumulator
と$function
の集計演算子を使用できます。 これらの演算子を使用して、JavaScript でカスタム集計式を定義できます。
map-reduce を集計パイプラインに置き換える例については、以下を参照してください。
詳細
集計パイプラインの詳細については、以下を参照してください。