Phoenix/Ecto: 列出所有帖子,包括最近3条评论的标题
Phoenix/Ecto: List all posts, include 3 latest comments’ title
我有一个 Post 架构,has_many 评论。我想在一页上列出所有带有评论的 post(我将单独使用分页),使用单个数据库查询,具有以下限制:
首先:我想将每个 post 的预加载限制为 3 个最新评论(不是全部,因为可能有数百个)。
其次:我只想预加载评论中的标题列,并避免使用 'text' 列,因为文本可能包含太多内容。
我的最终结果是:
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
...(等等)
无论我尝试过什么组合,我都无法限制每个 post 的嵌套评论数(我的限制总是限制评论总数,而不是在 per-post 的基础上)。
我的选择也无法仅从评论中加载标题。如果有经验的人有任何意见,我们将不胜感激。
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}]
预加载将预加载评论中的嵌套用户和图标列,但限制显然不适用于嵌套记录。
没有对此进行测试,但我认为可以在预加载时使用查询。但是我对语法有点不确定。
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
您可以使用 "pseudo" 版本,因为我没有时间实际检查代码,但它可以帮助您入门。
有其他选择,所以在这种情况下如何走完全取决于您。
首先你创建一个像这样的视图:
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 语法,这可能会因其他数据库而改变。
我有一个 Post 架构,has_many 评论。我想在一页上列出所有带有评论的 post(我将单独使用分页),使用单个数据库查询,具有以下限制:
首先:我想将每个 post 的预加载限制为 3 个最新评论(不是全部,因为可能有数百个)。
其次:我只想预加载评论中的标题列,并避免使用 'text' 列,因为文本可能包含太多内容。
我的最终结果是:
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
...(等等)
无论我尝试过什么组合,我都无法限制每个 post 的嵌套评论数(我的限制总是限制评论总数,而不是在 per-post 的基础上)。 我的选择也无法仅从评论中加载标题。如果有经验的人有任何意见,我们将不胜感激。
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}]
预加载将预加载评论中的嵌套用户和图标列,但限制显然不适用于嵌套记录。
没有对此进行测试,但我认为可以在预加载时使用查询。但是我对语法有点不确定。
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
您可以使用 "pseudo" 版本,因为我没有时间实际检查代码,但它可以帮助您入门。
有其他选择,所以在这种情况下如何走完全取决于您。
首先你创建一个像这样的视图:
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 语法,这可能会因其他数据库而改变。