我有一个Post架构,其中包含了很多评论。我想在一个页面上列出所有评论的帖子(我将单独使用分页),使用单个数据库查询,具有以下限制:
首先:我希望将每个帖子的预加载限制为3个最新评论(不是所有评论,因为可能有数百个评论)。
第二:我想从评论中仅预加载标题列,并避免使用“文本”列,因为文本可能包含太多内容。
我的最终结果将是:
Post 1 ──┬── Comment 1 Title
│── Comment 2 Title
└── Comment 3 Title
Post 2 ──┬── Comment 1 Title
│── Comment 2 Title
└── Comment 3 Title
Post 3 ──┬── Comment 1 Title
│── Comment 2 Title
└── Comment 3 Title
...(等)
无论我尝试过什么组合,我都不能限制每个帖子的嵌套评论数量(我的限制总是限制评论总数,而不是每个帖子)。 我的选择也无法仅从评论中加载标题。如果有经验的人有任何意见,那将非常感激。
PS:上面已经提出过,但为了进一步澄清,这是我的模型:
schema "posts" do
field :title, :string
field :slug, :string
field :active, :boolean, default: true
has_many :comments, App.Comment
timestamps()
end
schema "comments" do
field :title, :string
field :body, :string
field :email, :string
field :meta, :map
field :active, :boolean, default: false
belongs_to :post, App.Post
timestamps()
end
PPS:更具体一点,我想知道嵌套限制是否可能,与嵌套预加载相同:
query = from Post, preload: [:file, :image, {:comments, [:user, :icon]}], limit: [10, {:comments: 3}]
该预加载将在注释中预加载嵌套的用户和图标列,但显然限制对嵌套记录不起作用。
答案 0 :(得分:1)
你可以做的是“伪”版本,因为我没有时间实际检查代码,但它会让你开始。
还有其他选择,所以由你决定如何应对这种情况。
首先,你以某种方式创建一个视图:
create view posts_with_last_comments as
select
p.*,
(select array_agg(title) from comments where post_id = p.id order by inserted_at limit 3) as last_titles
from
posts p
然后在您的应用中执行以下操作:
query = from p in "posts_with_comments"
posts = MyApp.Repo.all(query)
请注意,我尝试使用postgresql语法,这可能会改变其他数据库。
答案 1 :(得分:0)
没有测试过这个,但我认为在预加载时可以使用查询。但是我对语法有点不确定。
query = from Post, preload: [:file, :image, {:comments, from(c in Comment, limit: 10), [:user, :icon]}], limit: 10
看看这里的第三个例子。 https://hexdocs.pm/ecto/Ecto.Repo.html#c:preload/3