【问题标题】:ActiveRecord, pgsql: query multiple records by multiple indexActiveRecord、pgsql:通过多个索引查询多条记录
【发布时间】:2019-01-21 17:45:51
【问题描述】:

在我的Users 表中,用户由@​​987654322@ 和location_id 对的唯一多重索引定义。
当我收到获取特定帐户/位置对的数据的请求时,我可以轻松检索这一对的数据:

account_location_hash = { account_id: 2, location_id: 3 }
user = User.find_by(account_location_hash)

但是,当我需要查找多个用户,并拥有一组哈希(数百对)时,没有简单的方法来获取我需要的实体,尽管我已经获得了这些实体的预期索引列表。
我尝试使用:

pairs_array = [{ account_id: 2, location_id: 3 },{ account_id: 1, location_id: 4 }]
user = User.where(pairs_array)

但这不起作用。

我可以找到更复杂的解决方案,例如构造一个 AND 和 OR 的查询,或者创建一个包含我得到的对的临时表并加入这些表,但没有一个感觉是正确的。
我错过了更简单的方法吗?

【问题讨论】:

  • 我最近遇到一种情况,我想通过一长串 ID 进行查询。我最终创建了一个临时表,它允许我使用一些连接而不是传递数百个 ID。这不是您问题的直接答案,但可能值得考虑。
  • 在这种情况下需要 OR,因为 AND 将导致 0 条记录。解决这个问题的简单程度取决于您使用的 Rails 版本。例如在 rails 5 @users = User.scoped; pairs_array.each {|pair| @users = @users.or(User.where(pair))} 就足够了
  • @engineersmnky,看起来很简单。尽管在 rails 4 中不推荐使用 scoped ,但这似乎可行:@users = User.none; pairs_array.each {|pair| @users = @users.or(User.where(pair))}
  • @isaac-fisher 很公平。考虑到循环中发生的额外范围,User.all 也足够了
  • @engineersmnky User.all 不会这样做,因为无论.or 添加多少,我们都会将其与所有元素一起保留(如 true OR false OR false...)。谢谢你的回答,真的很有帮助! (感谢上帝,我使用的是 rails 5 并且不需要 Arel)

标签: ruby-on-rails postgresql activerecord


【解决方案1】:

这是迄今为止我找到的最简单的解决方案(使用@engineersmnky 评论,rails 5):

pairs_array.reduce(User.none) {|users, pair| users.or(User.where(pair))}

【讨论】:

    【解决方案2】:

    我认为最简单的解决方案是:

    pairs_array = [{ account_id: 2, location_id: 3 },{ account_id: 1, location_id: 4 }]
    
    account_ids = []
    location_ids = []
    pairs_array.each do |h|
      account_ids << h[:account_id]
      location_ids << h[:location_id]
    end
    
    User.where('account_id IN (?) AND location_id IN (?)', account_ids, location_ids).load
    

    【讨论】:

    • 不,因为您还将获得 account_id: 2, location_id: 4 不在请求中的用户
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多