从多个模型中包含、选择、排序、限制(单个查询)
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
,然后来自 ConversationParticipant 的updated_at DESC
包括 对话 包括(消息发件人)=> 用户 包括来自 ConversationParticipant => 用户的其他参与者
注意:includes 和 select 很重要,因为这个问题旨在减少查询次数.
【问题讨论】:
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])
【讨论】:
以上是关于从多个模型中包含、选择、排序、限制(单个查询)的主要内容,如果未能解决你的问题,请参考以下文章
egg.js 24.13sequelize模型-字段限制排序分页
如何确保仅从特定表中选择第一条记录,该表可以在 DB2 中包含多个相同 ID 的记录