我需要找到所有用户的分数,只为每个用户选择两个最佳分数,最后将这些分数相加以创建排行榜。
让我举一个例子,说明我正在寻找什么以及我已经尝试过但没有成功。
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方式,但不幸的是你不能在$ group阶段对$ $ sort,$ limit进行限制,这意味着你不能只选择两个最佳分数。
通过操作简单的find()查询的返回文档,有没有办法可以使用mapReduce甚至Lodash?
答案 0 :(得分:0)
您可以使用lodash的_.sortBy()
,_.groupBy()
和_.map()
获得每位用户的2个最高分,并将其相加:
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>