您可以使用3.4.4
版本並使用$objectToArray
& $arrayToObject
在動態鍵和標籤值對之間切換。
這是一種在不改變結構的情況下達到目標的方法。
階段1到3:將動態鍵轉換爲鍵值對,然後在player1
上轉換$match
。
階段4至7:項目player
和opponent
並使用$objectToArray
到動態對手鍵轉換成關鍵值對隨後$unwind
+ $sort
+ $limit
。
階段8 & 9:將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"}}}
])