定義
構文
{ $maxN: { input: <expression>, n: <expression> } }
inputは、$maxNへの入力である 式 を指定します。 グループ内の各要素に対して評価が行われ、$maxNは最大のn値を保持します。nはグループあたりの結果数を制限し、nは定数であるか、$groupの_id値に依存する正の整数式である必要があります。
動作
NULL および欠損値
$maxNは null 値と欠損値を除外します。
グループから最大 個のnドキュメントを返す次の集計を検討してください。
db.aggregate( [ { $documents: [ { playerId: "PlayerA", gameId: "G1", score: 1 }, { playerId: "PlayerB", gameId: "G1", score: 2 }, { playerId: "PlayerC", gameId: "G1", score: 3 }, { playerId: "PlayerD", gameId: "G1" }, { playerId: "PlayerE", gameId: "G1", score: null } ] }, { $group: { _id: "$gameId", maximumThreeScores: { $maxN: { input: "$score", n: 4 } } } } ] )
この例では、次のことが行われます。
$documentsは、プレイヤーのスコアを含むリテラル ドキュメントを作成します。$groupはドキュメントをgameIdでグループ化します。 この例ではgameId、G1は 1 つのみです。PlayerDはスコアが欠落しており、PlayerEには nullscoreがあります。 これらの値は両方とも null と見なされます。maximumThreeScoresフィールドはinput : "$score"を伴う {$maxNとして指定され、配列として返されます。scoresを持つドキュメントは 3 つしかないため、maxNは最大 3 つのscoreフィールドを返しますが、n = 4は を実行します。
[ { _id: 'G1', maximumThreeScores: [ 3, 2, 1 ] } ]
アキュムレータと アキュムレータの比較$maxN$topN
$maxNと$topNのどちらのアキュムレータでも同様の結果が得られます。
一般に、
$maxNには、特定のソート順で最大値が見つかるという利点があります。nドキュメントの最大値を確認するには、$maxNを使用します。特定の並べ替え順序を保証する必要がある場合は、
$topNを使用します。出力値でソートしない場合は、
$topNを使用します。
制限事項
ウィンドウ関数と集計式のサポート
$maxNをアキュムレータとして使用できます。
メモリ制限に関する考慮事項
$maxNを呼び出す集計パイプラインには100 MB の制限が適用されます。 個々のグループでこの制限を超えると、集計はエラーで失敗します。
例
以下のドキュメントを持つgamescoresコレクションを考えてみましょう。
db.gamescores.insertMany([ { playerId: "PlayerA", gameId: "G1", score: 31 }, { playerId: "PlayerB", gameId: "G1", score: 33 }, { playerId: "PlayerC", gameId: "G1", score: 99 }, { playerId: "PlayerD", gameId: "G1", score: 1 }, { playerId: "PlayerA", gameId: "G2", score: 10 }, { playerId: "PlayerB", gameId: "G2", score: 14 }, { playerId: "PlayerC", gameId: "G2", score: 66 }, { playerId: "PlayerD", gameId: "G2", score: 80 } ])
1Scores 回のプレイで最大 3 つの を見つける
$maxNアキュムレータを使用して、1 つのゲームで最大 3 つのスコアを見つけることができます。
db.gamescores.aggregate( [ { $match : { gameId : "G1" } }, { $group: { _id: "$gameId", maxThreeScores: { $maxN: { input: ["$score","$playerId"], n:3 } } } } ] )
サンプル パイプライン:
$matchを使用して結果を単一のgameIdでフィルタリングします。 この場合は、G1ます。$groupを使用して結果をgameIdでグループ化します。 この場合は、G1ます。を使用して
$maxNinput : ["$score","$playerId"]に入力するフィールドを指定します。$maxNを使用して、n : 3とG1の最大 3 つのスコア要素を返します。
この操作は次の結果を返します。
[ { _id: 'G1', maxThreeScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] } ]
複数のゲームにわたる最大 3 スコアの検索
$maxNアキュムレータを使用して、各ゲームの最大nスコアを見つけることができます。
db.gamescores.aggregate( [ { $group: { _id: "$gameId", maxScores: { $maxN: { input: ["$score","$playerId"], n: 3 } } } } ] )
サンプル パイプライン:
$groupを使用して結果をgameIdでグループ化します。$maxNを使用して、n: 3を持つゲームごとに最大 3 つのスコア要素を返します。を使用して
$maxNinput: ["$score","$playerId"]に入力するフィールドを指定します。
この操作は次の結果を返します。
[ { _id: 'G1', maxScores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] }, { _id: 'G2', maxScores: [ [ 80, 'PlayerD' ], [ 66, 'PlayerC' ], [ 14, 'PlayerB' ] ] } ]
のグループキーに基づいて を計算n$group
また、 nの値を動的に割り当てることもできます。 この例では、 $cond式はgameIdフィールドで使用されています。
db.gamescores.aggregate([ { $group: { _id: {"gameId": "$gameId"}, gamescores: { $maxN: { input: ["$score","$playerId"], n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } } } } } } ] )
サンプル パイプライン:
$groupを使用して結果をgameIdでグループ化します。input : ["$score","$playerId"]を使用して$maxNに入力するフィールドを指定します。gameIdがG2の場合、nは 1、それ以外の場合、nは 3 になります。
この操作は次の結果を返します。
[ { _id: { gameId: 'G2' }, gamescores: [ [ 80, 'PlayerD' ] ] }, { _id: { gameId: 'G1' }, gamescores: [ [ 99, 'PlayerC' ], [ 33, 'PlayerB' ], [ 31, 'PlayerA' ] ] } ]