$maxN(集計アキュムレータ)
定義
構文
{ $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
ます。を使用して
$maxN
input : ["$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 つのスコア要素を返します。を使用して
$maxN
input: ["$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' ] ] } ]