Phoenix / Ecto:列出所有帖子,包括3个最新评论的标题

时间:2017-03-21 14:37:39

标签: elixir phoenix-framework ecto

我有一个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}]

该预加载将在注释中预加载嵌套的用户和图标列,但显然限制对嵌套记录不起作用。

2 个答案:

答案 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