Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 使用我的排行榜。尽可能减少工作量_Ruby On Rails_Ruby_Ruby On Rails 5 - Fatal编程技术网

Ruby on rails 使用我的排行榜。尽可能减少工作量

Ruby on rails 使用我的排行榜。尽可能减少工作量,ruby-on-rails,ruby,ruby-on-rails-5,Ruby On Rails,Ruby,Ruby On Rails 5,我有一个统计模型: Stat(id: integer, points: float, user_id: integer, match_id: integer, team_id: integer) 对于匹配模型: Match(id: integer, team_a_id: integer, team_b_id: integer) 下面是我的代码: stat= Stat .group(:user_id) .select("user_id, count(*) as matches_count,

我有一个统计模型:

Stat(id: integer, points: float, user_id: integer, match_id: integer, team_id: integer)
对于匹配模型:

 Match(id: integer, team_a_id: integer, team_b_id: integer)
下面是我的代码:

stat= Stat
.group(:user_id)
.select("user_id, count(*) as matches_count, sum(points) as score")
.where.not(points: 0)
.where.not(match_id: nil)

stat.each do |f|
  new_value = (f.sum_points.to_f / f.matches_count.to_f)
  f.sum_points = new_value.round(2)
  a << f
end

new_stat = a.sort_by(&:sum_points).reverse.first(10).flatten
stat=stat
.group(:用户\u id)
.选择(“用户id,计数(*)作为匹配项,总和(点数)作为分数”)
.where.not(分数:0)
.where.not(匹配id:nil)
统计每个do | f|
新值=(f.sum\u points.to\u f/f.matches\u count.to\u f)
f、 求和点=新值。四舍五入(2)

最有效的方法是使用sql计算数据,只检索前10名

基本上,现在您正在手动解析整个活动记录数组以计算和点,然后对所有数据进行排序和反转以检索前10位。正如您所说,当数据库中有大量数据时,性能将受到影响

以下是我的解决方案,它将仅使用sql查询计算和检索前10名:

stat = Stat.group(:user_id)
.select("user_id, round((sum(points) /count(*)), 2) as sum_points")
.where.not(points: 0).where.not(match_id: nil).order("sum_points DESC").first(10)

旁注:您正在滥用每个
进行实际映射。它应该是(而不是整个
stat.each
):
stat.map{f | f |(f.sum_points.to_f/f.matches_count.to_f)。round(2)}
。是的,这是可能的,在数据库中进行数学运算,
ORDER BY
LIMIT 10
。我已经使用此代码
new_stat=a.sort_BY(&:sum_points)。首先(10)得到了这个限制.flant
我用您的代码替换了我的代码
.map
。谢谢。
a.sort\u by.reverse
使用ruby进行排序和反转,效率极低。所有这些都应该在DB中完成,只需要从DB返回10行到Rails。我得到了正确的分数,但我还有另一个问题
count(*)
给出了记录数。因此,如果有53条记录,我得到/53我需要的是match_id,这是玩的游戏数。在我们的例子中,计数是基于组计算的,也就是说,在该组中,select
count(*)
返回该组中的记录数(如:用户的统计数),它不会返回数据库中所有统计数据的编号。如果需要该组中的匹配数,请使用
count(match\u id)
而不是
count(*)
,如果需要不同的匹配,请使用
count(distinct match\u id)