我有这样的代码只能获得用户青睐的产品。
@products = current_user.products.select {|product| product.count_favourited > 0 }
如果用户拥有大量产品,此代码将使用大量内存。问题是,我无法对查询执行过滤,因为赞成产品的用户数量存储在Redis上。
喜欢
def count_favourited
$redis.scard("some_key_based_on_product_id")
end
还有其他方法可以达到这个目的吗?
如何在内部使用find_each
呢?它将使用批处理?
@products = []
current_user.products.find_each do |product|
@products << product if product.count_favourited > 0
end
答案 0 :(得分:0)
怎么样:
current_user.products.where("products.count_favourited > 0")
或使用范围:
class Product < ActiveRecord::Base
scope :favourited, -> { where("count_favourited > 0") }
end
current_user.products.favourited
我错过了什么或者只是这么简单吗?
答案 1 :(得分:0)
我担心我对redis不太了解,但如果你主要担心的是内存使用,我会想到两个想法。首先,如果我正确地推断您在redis中使用了Set,那么sscan可能会有所帮助。至于Rails解决方案:
@products = current_user.products.keep_if {|product| product.count_favourited > 0 }
如果current_user.products
返回产品列表的副本,那么对所述副本进行就地修改应该是安全的。 keep_if
将做到这一点,从而避免为select做一个额外的副本所涉及的时间和记忆(当然,这是以就地操作所需的时间为代价)。
答案 2 :(得分:0)
如何在内部使用find_each,它将使用批处理?
是的,如果您只关心内存使用情况(而不是执行速度),那么批处理将解决您的问题。减少内存使用量正是它的用途(并没有带来任何其他好处)。
你可以反过来做吗?即,请redis为您提供用户喜欢的产品ID?我想我能猜到答案......