定義
構文
{    $bottomN:       {          n: <expression>,          sortBy: { <field1>: <sort order>, <field2>: <sort order> ... },          output: <expression>       } } 
- nは、グループごとの結果数を制限し、定数であるか、- $groupの- _id値に依存する正の整数式である必要があります。
- sortBy は、 - $sortに似た構文で結果の順序を指定します。
- outputは、グループ内の各要素の出力を表し、任意の 式 にすることができます。
動作
NULL および欠損値
- $bottomNは、null 値をフィルタリングで除外しません。
- $bottomNは、出力に保持される欠落値を null に変換します。
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",             playerId:                {                   $bottomN:                      {                         output: [ "$playerId", "$score" ],                         sortBy: { "score": -1 },                         n: 3                      }                }       }    } ] ) 
この例では、次のことが行われます。
- $documentsは、プレイヤーのスコアを含むリテラル ドキュメントを作成します。
- $groupはドキュメントを- gameIdでグループ化します。 この例では- gameId、- G1は 1 つのみです。
- PlayerDはスコアが欠落しており、- PlayerEには null- scoreがあります。 これらの値は両方とも null と見なされます。
- playerIdフィールドと- scoreフィールドは- output : ["$playerId"," $score"]として指定され、配列値として返されます。
- sortBy: { "score" : -1 }により、null 値は返された- playerId配列の末尾にソートされます。
[    {       _id: "G1",       playerId: [ [ "PlayerA", 1 ], [ "PlayerD", null ], [ "PlayerE", null ] ]    } ] 
BSON データ型ソート順
異なるタイプをソートする場合、順序を決定するためにBSON データ型の順序が使用されます。 例として、値が string と数値で構成されるコレクションを考えてみましょう。
- 昇順ソートでは、string 値は数値の後にソートされます。 
- 降順ソートでは、string 値が数値の前にソートされます。 
db.aggregate( [    {       $documents: [          { playerId: "PlayerA", gameId: "G1", score: 1 },          { playerId: "PlayerB", gameId: "G1", score: "2" },          { playerId: "PlayerC", gameId: "G1", score: "" }       ]    },    {       $group:          {             _id: "$gameId",             playerId: {                $bottomN:                {                   output: ["$playerId","$score"],                   sortBy: {"score": -1},                   n: 3                }             }          }    } ] ) 
この例では、次のことが行われます。
- PlayerAは整数スコアを持ちます。
- PlayerBは string- "2"スコアを持ちます。
- PlayerCには空のstringスコアがあります。
並べ替えは{ "score" : -1 }の降順であるため、string リテラル値はPlayerAの数値スコアより前にソートされます。
[    {       _id: "G1",       playerId: [ [ "PlayerB", "2" ], [ "PlayerC", "" ], [ "PlayerA", 1 ] ]    } ] 
制限事項
ウィンドウ関数と集計式のサポート
$bottomN 集計式としてサポートされていません。
$bottomN はwindow operatorとしてサポートされています。
メモリ制限に関する考慮事項
$bottomN集計パイプライン内のグループには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 } ]) 
3 つの最低を見つける Scores
$bottomNアキュムレータを使用すると、単一のゲーム内で最もスコアの低いプレイヤーを見つけることができます。
db.gamescores.aggregate( [    {       $match : { gameId : "G1" }    },    {       $group:          {             _id: "$gameId",             playerId:                {                   $bottomN:                   {                      output: ["$playerId", "$score"],                      sortBy: { "score": -1 },                      n:3                   }                }          }    } ] ) 
サンプル パイプライン:
- $matchを使用して結果を単一の- gameIdでフィルタリングします。 この場合は、- G1ます。
- $groupを使用して結果を- gameIdでグループ化します。 この場合は、- G1ます。
- 結果を降順で並べ替えるには、 - { "score": -1 }による並べ替えを使用します。
- を使用して - $bottomN- output : ["$playerId"," $score"]から出力するフィールドを指定します。
- $bottomNを使用して、- n : 3を持つ- G1のゲームで最低の- scoreを持つ下位 3 つのドキュメントを返します。
この操作は次の結果を返します。
[    {       _id: "G1",       playerId: [ [ "PlayerB", 33 ], [ "PlayerA", 31 ], [ "PlayerD", 1 ] ]    } ] 
このクエリに相当する SQL は次のとおりです。
SELECT T3.GAMEID,T3.PLAYERID,T3.SCORE FROM GAMESCORES AS GS JOIN (SELECT TOP 3          GAMEID,PLAYERID,SCORE          FROM GAMESCORES          WHERE GAMEID = "G1"          ORDER BY SCORE) AS T3             ON GS.GAMEID = T3.GAMEID GROUP BY T3.GAMEID,T3.PLAYERID,T3.SCORE    ORDER BY T3.SCORE DESC 
複数のゲームにわたる最低スコア ドキュメントの検索
$bottomNアキュムレータを使用して、各ゲームで最低スコアのプレイヤーを見つけることができます。
db.gamescores.aggregate( [       {          $group:          { _id: "$gameId", playerId:             {                $bottomN:                   {                      output: [ "$playerId","$score" ],                      sortBy: { "score": -1 },                      n: 3                   }             }          }       } ] ) 
サンプル パイプライン:
- $groupを使用して結果を- gameIdでグループ化します。
- を使用して - $bottomN- output : ["$playerId", "$score"]から出力するフィールドを指定します。
- 結果を降順で並べ替えるには、 - { "score": -1 }による並べ替えを使用します。
- $bottomNを使用して、- n: 3を持つゲームごとに、最低の- scoreを持つ下位 3 つのドキュメントを返します。
この操作は次の結果を返します。
[    {       _id: "G1",       playerId: [ [ "PlayerB", 33 ], [ "PlayerA", 31 ], [ "PlayerD", 1 ] ]    },    {       _id: "G2",       playerId: [ [ "PlayerC", 66 ], [ "PlayerB", 14 ], [ "PlayerA", 10 ] ]    } ] 
このクエリに相当する SQL は次のとおりです。
SELECT PLAYERID,GAMEID,SCORE FROM(    SELECT ROW_NUMBER() OVER (PARTITION BY GAMEID ORDER BY SCORE DESC) AS GAMERANK,    GAMEID,PLAYERID,SCORE    FROM GAMESCORES ) AS T WHERE GAMERANK >= 2 ORDER BY GAMEID 
のグループキーに基づいて を計算n$group
また、 nの値を動的に割り当てることもできます。 この例では、 $cond式はgameIdフィールドで使用されています。
db.gamescores.aggregate([    {       $group:       {          _id: {"gameId": "$gameId"},          gamescores:             {                $bottomN:                   {                      output: "$score",                      n: { $cond: { if: {$eq: ["$gameId","G2"] }, then: 1, else: 3 } },                      sortBy: { "score": -1 }                   }             }       }    } ] ) 
サンプル パイプライン:
- $groupを使用して結果を- gameIdでグループ化します。
- を使用して - $bottomN- output : "$score"から出力するフィールドを指定します。
- gameIdが- G2の場合、- nは 1、それ以外の場合、- nは 3 になります。
- 結果を降順で並べ替えるには、 - { "score": -1 }による並べ替えを使用します。
この操作は次の結果を返します。
[    { _id: { gameId: "G2" }, gamescores: [ 10 ] },    { _id: { gameId: "G1" }, gamescores: [ 33, 31, 1 ] } ]