【问题标题】:Rails - preprocessing in DB layer (PG)Rails - DB层(PG)中的预处理
【发布时间】:2016-05-25 00:43:56
【问题描述】:

鉴于我使用 Postgres 并且有这个方法:

  def undelivered_messages(datetime)
    messages = {}
    @current_user.conversations.includes(:user_messages).each do |c|
      messages[c.id] = c.user_messages.where('user_id != ? AND created_at > ?', @current_user.id, datetime)
    end
    JSON.generate(messages)
  end

我希望这个输出看起来像(不包括 JSON.generate()):

{1=>[m1,m2,m3], 2=>[m1,m2,m3]}

我想知道,我可以通过数据库级​​别的一些 SQL 查询来做这件事,所以数据库准备哈希(或 JSON 对象),它希望更快,因为 Ruby 很慢,而数据库不是。

【问题讨论】:

    标签: ruby-on-rails json postgresql


    【解决方案1】:

    你可以试试这样的:

    UserMessage
     .joins(:conversation)
     .where('user_messages.user_id != ? AND user_messages.created_at > ?', @current_user.id, datetime)
     .where(conversations: { user_id: @current_user.id })
     .group_by(&:conversation_id)
    

    【讨论】:

    • group_by 是 ruby​​ 方法,所以它会在 ruby​​ 中对消息进行分组。我的观点是在数据库层是否有可能。 pg array_agg 似乎很接近,但我不确定
    • 也不知道,如果我想按 id 对记录进行分组,我会使用这种调用...这里的优点是你可以用一个单一的方法检索你需要的东西查询,而不是查询用户的对话,然后查询用户消息以构建该哈希......也许这就是它有点慢的原因。如果有人知道正确的答案,我会关注这个帖子,那会很酷(因为你节省了额外的group_by
    • 如果您只是想进行分组,那么可以,您可以使用 array_agg 为每个 ID 构建一个 Postgres 数组。 SELECT array_agg(user_id) FROM ... GROUP BY conversation_id 之类的。请注意,如果您有很多对话或与很多用户的对话,您可能仍然会对刚刚要求 ruby​​ 处理(然后是 GC)的数据量感到不满。
    • dockyard.com/blog/2014/05/27/… 超级花哨,现在我需要弄清楚我的情况是如何暗示这一点的
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多