3.4.4
バージョンを使用し、$objectToArray
& $arrayToObject
を使用すると、動的キーとラベル値のペアを切り替えることができます。
これは、構造を変更することなく、後の作業を達成する方法の1つです。
ステージ1〜3:ダイナミックキーをキー値のペアに変換し、次に$match
をplayer1
に変換します。
ステージ7を介して、4:プロジェクトplayer
とopponent
と$unwind
+ $sort
+ $limit
続いてキー値ペアに動的相手キーを変換する$objectToArray
を使用します。
ステージ8 opponent
をキー値ペアの配列にグループ化し、その後に$arrayToObject
をグループ化して、キー値のペアをダイナミックキーに変換します。
db.collection.aggregate([
{$project: {keyvalarr: {$objectToArray: "$$ROOT"} }},
{$unwind:"$keyvalarr"},
{$match:{"keyvalarr.k":"player1"}},
{$project:{player:"$keyvalarr.k", opponent: {$objectToArray: "$keyvalarr.v"}},
{$unwind:"$opponent"},
{$sort:{"opponent.v":-1}},
{$limit:3},
{$group:{_id:null, player:{$first:"$player"}, opponent:{$push:"$opponent"}}},
{$project:{result: {$arrayToObject:"$opponent"}}}
])
下位バージョンの場合は構造を以下のように変更する必要があります。インデックスを使用することができます。 (推奨)
{player:"player1", opponent: [{player:"player2", rounds: 10},{player:"player3", rounds: 25}, {player:"player4", rounds: 8}, {player:"player5", rounds: 12}]}
以下の集約パイプラインに単純化することができます。
db.collection.aggregate([
{$match:{"player":"player1"}},
{$unwind:"$opponent"},
{$sort:{"opponent.rounds":-1}},
{$limit:3},
{$group:{_id:null, player:{$first:"$player"}, opponent:{$push:"$opponent"}}}
])