从多个模型中包含、选择、排序、限制(单个查询)

Posted

技术标签:

【中文标题】从多个模型中包含、选择、排序、限制(单个查询)【英文标题】:Include, Select, Sort, Limit from multiple models (single query) 【发布时间】:2015-01-08 16:06:41 【问题描述】:

我需要创建一个包含来自下表的数据的单个查询:

*对话:将用户之间的消息分组的模型

class Conversation < ActiveRecord::Base
  # Associations
  has_many :messages, dependent: :destroy
  has_many :conversation_participants
  has_many :users, :through => :conversation_participants
  ## Attributes title, created_at, updated_at
end

* ConversationParticipant:跟踪对话用户的模型

class ConversationParticipant < ActiveRecord::Base
  ## Associations
  belongs_to :conversation
  belongs_to :user
  ## Attributes conversation_id, user_id, seen, created_at, updated_at
end

* 消息:跟踪内容和发件人的模型

class Message < ActiveRecord::Base
  belongs_to :conversation
  belongs_to :sender, :class_name => "User"
  ## Attributes sender_id, content, conversation_id, created_at, updated_at
end

*User:具有name属性的模型


如何在单个查询中获取以下内容?

    limit (5) 条来自 uniq Conversation Message 的近期消息 哪里 user_id = current_user.id 来自 ConversationParticipant 订购 seen = false,然后来自 ConversationParticipantupdated_at DESC 包括 对话 包括消息发件人)=> 用户 包括来自 ConversationParticipant => 用户的其他参与者

注意:includesselect 很重要,因为这个问题旨在减少查询次数.

【问题讨论】:

Message 有 ConversationParticipant 而不是 User 有意义吗?另外,我不清楚您在 1 号下的 uniq 对话消息是什么意思。您目前使用的是什么?查看您当前的查询可能会帮助我了解您的目标。此外,查看您期望返回的对象的外观也可能会有所帮助。此外,这可能是数据库视图的一个很好的候选者,具体取决于您想用这些信息做什么,并且可以大大简化查询...... 【参考方案1】:

这是我包含所有需要的模型的方式,此查询被转换为 5 个 sql 查询,因为 preload 不加入(在单独的查询中运行)。

Message.joins("LEFT JOIN messages AS m ON messages.id != m.id 
              AND m.conversation_id = messages.conversation_id 
              AND messages.created_at < m.created_at")
       .where('m.id IS NULL')
       .joins("INNER JOIN conversation_participants AS cp 
              ON cp.conversation_id = messages.conversation_id 
              AND cp.user_id = #user_id")
       .order("cp.seen, cp.updated_at DESC")
       .limit(5)
       .includes(:sender)
       .includes(conversation: [conversation_participants: :user])

【讨论】:

以上是关于从多个模型中包含、选择、排序、限制(单个查询)的主要内容,如果未能解决你的问题,请参考以下文章

Mongodb:聚合排序限制查询的索引?

egg.js 24.13sequelize模型-字段限制排序分页

如何确保仅从特定表中选择第一条记录,该表可以在 DB2 中包含多个相同 ID 的记录

PHP 的 PDO 可以限制为单个查询吗?

Laravel - 模型自引用belongsToMany与其他关系和具有多个限制的查询

在 Postgres 的单个索引中包含多个列