Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.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 Rails订单记录符合大多数条件_Ruby On Rails_Ruby_Performance - Fatal编程技术网

Ruby on rails Rails订单记录符合大多数条件

Ruby on rails Rails订单记录符合大多数条件,ruby-on-rails,ruby,performance,Ruby On Rails,Ruby,Performance,对关联中存在的元素进行排序,其中第一个元素将是最选定关联中存在的元素。 换句话说,大多数关联的排序元素都存在于给定的列表中。 这听起来很复杂,所以这里是一个工作示例,但速度非常慢 我们想按大多数司机能驾驶的程度对汽车进行分类 # we have some ids of driver seleted by user dynamic_drivers_ids = [1,2,3,100,5] @cars = Car.all.includes(:driving_levels) @cars.sort_by

对关联中存在的元素进行排序,其中第一个元素将是最选定关联中存在的元素。 换句话说,大多数关联的排序元素都存在于给定的列表中。 这听起来很复杂,所以这里是一个工作示例,但速度非常慢

我们想按大多数司机能驾驶的程度对汽车进行分类

# we have some ids of driver seleted by user
dynamic_drivers_ids = [1,2,3,100,5]

@cars = Car.all.includes(:driving_levels)
@cars.sort_by {|e| (e.driving_level.map(&:driver_id) & dynamic_drivers_ids ).size * -1 }
装载大约需要1秒,只有20辆车。 但现在我们有100辆车的情况,需要几十年的时间来计算

我们如何才能像那样编写sql请求订单? 它不起作用,但显示了一些逻辑:

Car.includes(:driving_levels).order("driving_level.id IN = ? AND driving_level.size", dynamic_drivers_ids)
Db表如下所示:

class Car
  has_many :driving_levels
  has_many :drivers, through: driving_levels


class DrivingLevel
  belongs_to :car
  belongs_to :driver

class Driver
  has_many :driving_levels
  has_many :cars, through: driving_levels

左连接
驱动\u级别
如何,但只有那些在
动态\u驱动\u id
中具有
驱动\u id
的级别(希望
动态\u驱动\u id
不是来自用户,否则容易发生sql注入)?然后您可以根据驾驶级别的计数进行分组和排序

它看起来是这样的:

 Car
   .joins("LEFT OUTER JOIN driving_levels ON
           driving_levels.id = cars.driving_level_id AND 
           driving_level.driver_id IN (#{dynamic_drivers_ids})")
   .group(:id).order("COUNT(driving_levels.id)")

首先,您应该在此处使用
where
references

dynamic_drivers_ids = [1,2,3,100,5]

@cars = Car.includes(:driving_level).
            references(:driving_level).
            where(driving_level: {id: dynamic_drivers_ids})
这里发生的事情是,它将连接表
cars
driving\u level
,并仅拉取
driving\u level
记录,这些记录具有这些id(您不必执行:
e.driving\u level.map(&:driver\u id)和dynamic\u drivers\u id
)。您将不再提取所有
驾驶级别的
记录。
这应该会大大加快

次要:按关联排序。最简单的方法是使用列,它计算我们的关联,然后在上面排序:

@cars = Car.select('COUNT(driving_levels.id) as driving_levels_size').
            includes(:driving_level).
            references(:driving_level).
            where(driving_level: {id: dynamic_drivers_ids}).
            group('cars.id, driving_levels.id').
            order('driving_levels_size')

这将返回正确的顺序和正确的关联记录。

如果
driving\u levels
包含
driver\u id
1,2,3100,5的记录,请尝试此操作

select_clause = <<~SQL
  cars.*,
  ( SELECT count(DISTINCT driver_id) FROM driving_levels
    WHERE driver_id IN (1,2,3,100,5)
       OR car_id=cars.id ) as driver_cnt
SQL

Car
  .select(select_clause)
  .order('driver_cnt DESC')
  .to_a

select\u clause=您的数据库是什么?似乎
汽车属于驾驶级别
。所以看到
driving\u level.map(&:driver\u id)
很奇怪。请提供模型代码。我已经用表更新了问题。我认为这属于codereview,因为它是代码优化。有一个错误PG::UndefinedColumn:错误:列“driving_levels_size”不存在不确定是否可以将数组插入sql字符串:(是的,我的错误,您需要括号。已编辑