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

式、アキュムレータ、ウィンドウ関数

$avg、$sum、$max などの一部の集計演算子は複数のコンテキストに表示され、各コンテキストで演算子の動作が異なります。 (例: )。

  • 式として、$avg は配列内の要素の平均を返します。

  • アキュムレータとして、$avg はドキュメントのグループ全体の 値の平均を返します。

  • ウィンドウ関数として、$avg はウィンドウ内のドキュメントの 値の平均を返します。

演算子を含む ステージは、その動作を決定します。同じ演算子名でも、使用する場所に応じて異なる引数を受け入れ、異なる結果を返す場合があります。このページでは、3 つのコンテキストとそれらを曖昧にする方法について説明します。

次の図は、式、アキュムレータ、ウィンドウ関数の実行方法を概念化したものです。

次の表は、3 つの演算子タイプの違いをまとめたものです。

演算子タイプ
動作
使用できる場所

式

各入力ドキュメントに対して評価され、ドキュメントごとに 1 つの値を返します。

$project、$addFields 、およびその他の多くのステージに加えて、$expr 述語と検索コマンド プロジェクションを使用します。

アキュムレータ

入力ドキュメントのグループを集計し、グループごとに 1 つの集計値を返します。

ウィンドウ関数

入力ドキュメントのウィンドウに対して評価され、ドキュメントごとに 1 つの値を返します。

式は、単一の 入力ドキュメントの値に解決されます。式は入力をミューテーションしません。

式演算子は引数の配列を受け入れ、次のジェネリック形式をとります。

{ <operator>: [ <argument1>, <argument2> ... ] }

演算子が引数を 1 つだけ受け入れる場合は、外側の配列を省略できます。

式は、アキュムレータやウィンドウ関数の引数も提供します。例、{ $sum: "$price" } では、フィールドパス"$price" は式です。

詳細については、「 式 」を参照してください。

アキュムレータは、変数数の入力ドキュメントにわたって合計、最大、最小などの単一の集計値を計算します。実際の実装では、アキュムレータは グループ操作を実行中に処理するドキュメント間で状態を維持します。

$groupステージによって返される出力ドキュメントの数は、グループの数と同じです。これらのグループごとに、アキュムレータがグループ全体の集計値を計算します。

グループ化操作を実行する集計パイプラインステージでアキュムレータを使用できます。

詳細については、「 アキュムレータ 」を参照してください。

ウィンドウ関数は、現在のドキュメントを基準にして定義されたドキュメントの範囲であるウィンドウに基づいて値を返します。 $setWindowFields ステージの partitionBy、sortBy、window フィールドを使用してウィンドウを定義します。

アキュムレータとウィンドウ関数の両方として機能する演算子の場合、その差は演算子が集計する内容と返される値の数です。

  • アキュムレータとして、演算子はドキュメントのグループを集計し、グループの単一の値を返します。

  • ウィンドウ関数として、 演算子はドキュメントのウィンドウを集計し、各ドキュメントの値を返します。

ウィンドウ関数は$setWindowFields ステージでのみ使用できます。$setWindowFields $rankは、 や$shift などのウィンドウ固有の演算子もサポートしています。

詳しくは、「 ウィンドウ関数 」を参照してください。

このページの例では、sample_mflix データセット のデータを使用しています。自己管理型 MongoDB 配置にこのデータセットをロードする方法の詳細については、「サンプル データセットのロード」を参照してください。サンプル データベースに何らかの変更を加えた場合は、今ページの例を実行するには、データベースを削除して再作成する必要がある可能性があります。

次の例では、3 つのすべてのコンテキストで $sum を使用しています。それぞれが異なる結果を返します。この値は、コンテキストが演算子の動作を決定する方法を示しています。

次の例では、$sum を式として使用して、各ドキュメント内に 2 つのフィールドを追加しています。パイプラインは、一致するドキュメントごとに 1 の合計を返します。

db.movies.aggregate( [ { $match: { title: { $in: [ "The Godfather", "Inception", "The Dark Knight" ] } } }, { $project: { _id: 0, title: 1, totalAwards: { $sum: [ "$awards.wins", "$awards.nominations" ] } } }, { $sort: { totalAwards: -1 } }] )

次の例では、$sum をアキュムレータとして使用して、各グループ内の各ドキュメントの 1 つのフィールドを合計します。パイプラインは、 各ドキュメントごとに 1 つの合計ではなく、各コンテンツ評価に対して 1 つの合計を返します。

db.movies.aggregate( [ { $match: { rated: { $in: [ "G", "PG", "PG-13", "R" ] }, "imdb.votes": { $type: "int" } } }, { $group: { _id: "$rated", totalVotes: { $sum: "$imdb.votes" } } }, { $sort: { _id: 1 } }] )

次の例では、$sum をウィンドウ関数として使用して、ドキュメントのウィンドウ全体で 1 つのフィールドを合計します。パイプラインは各ドキュメントの実行中の合計を返します。その合計はドキュメントのウィンドウによって異なります。

db.movies.aggregate( [ { $match: { genres: "Musical", year: { $in: [ 2009, 2010 ] }, "imdb.rating": { $type: "double" }, "imdb.votes": { $gt: 0 } } }, { $setWindowFields: { partitionBy: "$year", sortBy: { title: 1 }, output: { cumulativeVotesInYear: { $sum: "$imdb.votes", window: { documents: [ "unbounded", "current" ] } }, rankInYear: { $documentNumber: {} } } } }, { $project: { _id: 0, title: 1, year: 1, "imdb.votes": 1, cumulativeVotesInYear: 1, rankInYear: 1 } }, { $sort: { year: 1, title: 1 } }] )