Laravel 获取集合中某行的 position/rank

Laravel get the position/rank of a row in collection

我有一个 排行榜leaderboard_scores table.

leaderboard_scores 有列:idleaderboard_id , player_id, 分数.

Leaderboard 模型中,我定义了 hasManyLeaderboardScore 的关系:

public function scores()
{
    return $this->hasMany('App\LeaderboardScore')->orderBy('score', 'desc');
}

现在我想获得某个玩家在特定排行榜中的排名。

所以在控制器中,我循环查找给定 player_id:

的位置
$score = $leaderboard->scores;

$scoreCount = $scores->count();
$myScore = $scores->where('player_id', $request->query('player_id'));

if ($myScore) { // If got my score
    $myRank = 1;
    for ($i = 0; $i < $scoreCount; $i++) {
        if ($scores[$i]->player_id == $request->query('player_id')) {
            $myRank = $i + 1;
            break;
        }
    }
    // Output or do something with $myRank
}

它工作正常,但我担心性能,当我有十万名玩家并且他们不断获得他们的排名时。 for 循环似乎不是一个好的选择。

我应该使用原始数据库查询吗?或者有更好的主意吗?

这里有一些想法

  • 不是每次收到请求都计算排名,而是遍历所有数据。您可以只将玩家排名存储在数据库或缓存中。你只需要在新玩家 added/deleted 或分数改变时计算它们。

检查缓存: https://laravel.com/docs/5.4/redis

  • 如果你仍然想每次都计算它,你可以使用 mysql 比原始循环更优化的排名函数

Mysql 排名:http://www.folkstalk.com/2013/03/grouped-rank-function-mysql-sql-query.html