高效 rails 查询包括记录(returns 布尔值)
efficient rails query includes record (returns boolean)
我的人有分数,我想要一种有效的方法来查询给定用户是否在前 X 个用户中。
# person.rb
class Person
scope :top_score, -> {order('score DESC')}
scope :page_limit, -> { limit(10) }
def self.in_top_score(id)
top_score.page_limit.something_something_soemthign?
end
end
之前在做:
user.id.in?(top_score.page_limit.pluck(:id))
但我更愿意将此检查移至数据库以防止 hundreds/thousands 记录的对象序列化。
Person.order('score DESC').select([:score, :id]).limit(1)
Person Load (0.5ms) SELECT score, id FROM `people` ORDER BY score DESC LIMIT 1
=> [#<Person id: "dxvrDy...", score: 35>]
现在检查该列表中是否存在其他用户^^
Person.order('score DESC').select([:score, :id]).limit(1).exists?({id: "c_Tvr6..."})
Person Exists (0.3ms) SELECT 1 AS one FROM `people` WHERE `people`.`id` = 'c_Tvr6...' LIMIT 1
=> true
return 正确但应该 return 错误
更新答案
抱歉,我原来的回答不正确。 (exists?
查询显然使用了 LIMIT 1
并从 page_limit
范围覆盖了 LIMIT 10
,并且显然也抛出了 ORDER BY
子句。完全错误!: -p)
这个呢?它有点不太优雅,但我这次实际测试了答案:-p,它似乎按预期工作。
def self.in_top_score?(id)
where(id: id).where(id: Person.top_score.page_limit).exists?
end
这是我的测试(使用 Rails 4.2.6)和它生成的 SQL(使用子查询)的示例用法:
pry(main)> Person.in_top_score?(56)
Person Exists (0.4ms) SELECT 1 AS one FROM "people" WHERE "people"."id" = AND "people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."score" DESC LIMIT 10) LIMIT 1 [["id", 56]]
=> false
在我的测试中,与您的原始版本相比,这确实至少有一点性能提升。
原回答
top_score.page_limit.exists?(user.id)
http://apidock.com/rails/ActiveRecord/FinderMethods/exists%3F
我的人有分数,我想要一种有效的方法来查询给定用户是否在前 X 个用户中。
# person.rb
class Person
scope :top_score, -> {order('score DESC')}
scope :page_limit, -> { limit(10) }
def self.in_top_score(id)
top_score.page_limit.something_something_soemthign?
end
end
之前在做:
user.id.in?(top_score.page_limit.pluck(:id))
但我更愿意将此检查移至数据库以防止 hundreds/thousands 记录的对象序列化。
Person.order('score DESC').select([:score, :id]).limit(1)
Person Load (0.5ms) SELECT score, id FROM `people` ORDER BY score DESC LIMIT 1
=> [#<Person id: "dxvrDy...", score: 35>]
现在检查该列表中是否存在其他用户^^
Person.order('score DESC').select([:score, :id]).limit(1).exists?({id: "c_Tvr6..."})
Person Exists (0.3ms) SELECT 1 AS one FROM `people` WHERE `people`.`id` = 'c_Tvr6...' LIMIT 1
=> true
return 正确但应该 return 错误
更新答案
抱歉,我原来的回答不正确。 (exists?
查询显然使用了 LIMIT 1
并从 page_limit
范围覆盖了 LIMIT 10
,并且显然也抛出了 ORDER BY
子句。完全错误!: -p)
这个呢?它有点不太优雅,但我这次实际测试了答案:-p,它似乎按预期工作。
def self.in_top_score?(id)
where(id: id).where(id: Person.top_score.page_limit).exists?
end
这是我的测试(使用 Rails 4.2.6)和它生成的 SQL(使用子查询)的示例用法:
pry(main)> Person.in_top_score?(56)
Person Exists (0.4ms) SELECT 1 AS one FROM "people" WHERE "people"."id" = AND "people"."id" IN (SELECT "people"."id" FROM "people" ORDER BY "people"."score" DESC LIMIT 10) LIMIT 1 [["id", 56]]
=> false
在我的测试中,与您的原始版本相比,这确实至少有一点性能提升。
原回答
top_score.page_limit.exists?(user.id)
http://apidock.com/rails/ActiveRecord/FinderMethods/exists%3F