如何在不将所有记录加载到内存中的情况下查询所有没有特定关联的记录?

时间:2013-10-31 23:21:37

标签: ruby-on-rails postgresql activerecord ruby-on-rails-4

如果我想要一份周日开放的所有商店的清单,我会

Shop.includes(:opening_times).where("opening_times.day =?", 'Sunday')

有没有办法获得周日关闭的所有商店的清单?也就是说,所有与日期栏都是“星期天”的记录无关的商店?

我问了这个问题here并接受了答案。但是,现在我的数据库变得太大了,无法通过首先将所有打开的商店加载到内存中来解决这个问题。有没有办法在没有首先获得所有开放商店的数组并将该数组传回数据库的情况下执行此操作?

3 个答案:

答案 0 :(得分:2)

可能有更多Railsy方式,但只有一个查询(和子查询):

Shop.where("shop_id NOT IN (select opening_times.shop_id from opening_times where opening_times.day = 'Sunday')")

或者,根据链接的问题,您可以使用pluck

进行改进
shop_ids = Shop.includes(:opening_times).where("opening_times.day = ?", 'Sunday').pluck(:id)
shops = Shop.where("id NOT IN(?)", shop_ids)

您正在使用的当前方法(map(&:id))正在为每一行实例化对象,而pluck(:id)将执行select id查询。

答案 1 :(得分:1)

没有map的更快捷的方法就是取代id。

open = Shop.includes(:opening_times).where(opening_times: { day: 'Sunday' }).pluck(:id)
closed = Shop.where.not(id: open)

答案 2 :(得分:0)

我不确定我明白你在问什么,但我会去。

当我需要查询具有关联的对象时,我通常会为关联对象的#创建一个计数器缓存并进行查询。所以,最后,您的查询将如下所示:

Shop.include(:opening_times).where("opening_times.sunday_count", 0)