2016-09-16 5 views
0

すべてのユーザーを検索し、各ユーザーの2つのベストスコアのみを選択し、それらのスコアを合計してリーダーボードを作成する必要があります。特定の物件に対して特定の金額を制限した文書を集計します。

私が探しているものと、私がすでに試したものの、成功していないものの例を挙げてみましょう。私はで終わるしたい何

Users Collection: 
[ 
    {user: "userA", score:10, game: 12}, 
    {user: "userA", score:20, game: 12}, 
    {user: "userA", score:7, game: 12}, 
    {user: "userB", score:10, game: 12}, 
    {user: "userB", score:3, game: 12}, 
    {user: "userB", score:7, game: 12} 
] 

これです:

[ 
    {user:"userA", score:30, game:12}, 
    {user:"userB", score:17, game:12} 
] 

は私が凝集とのmongoの道を進んで試してみたが、残念ながらあなたが$グループステージ上の$ソート、$を制限することはできませんアグリゲーションは2つのベストスコアだけを選択することはできません。

mapReduceやLodashを使っても、単純なfind()クエリの返されたドキュメントを操作することでこれを行う方法はありますか?

答えて

0

あなたは、各ユーザーの2点の最高得点を取得し、それらを合計するlodashの_.sortBy()_.groupBy()、および_.map()を使用することができます。

var arr = [ 
 
    {user: "userA", score:10, game: 12}, 
 
    {user: "userA", score:20, game: 12}, 
 
    {user: "userA", score:7, game: 12}, 
 
    {user: "userB", score:10, game: 12}, 
 
    {user: "userB", score:3, game: 12}, 
 
    {user: "userB", score:7, game: 12} 
 
]; 
 

 
var result = _(arr) // start a lodash's chain 
 
    .sortBy(function(value) { // sort the array descending 
 
    return -value.score; 
 
    }) 
 
    .groupBy('user') // group by the user 
 
    .map(function(arr) { // map each user 
 
    var score = arr[0].score + (arr[1] ? arr[1].score : 0); // the score should be a combination of the 1st two items (if there are two) 
 
    return Object.assign({}, arr[0], { score, score }); // assign to new object, with the calculated score 
 
    }) 
 
    .value(); // extract the result from the chain 
 

 
console.log(result);
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.15.0/lodash.min.js"></script>

+0

また、完成のために私はそこだと思いますソートされたリーダーボードを持つためには、チェーンの最後のsortByでなければなりません。 – MasterBug

関連する問題