使用 Ecto 的嵌套子查询

Nested subqueries with Ecto

使用 Ecto v2.2.6,Phoenix 1.3

我有一个带有新闻源的博客应用程序。它是这样工作的:

我想使用 Ecto.Query 从给定用户关注的用户那里获取新闻源项目列表。


快速背景。以下是对象:

用户

mix phx.gen.json Accounts User users email:string password:string

Post

mix phx.gen.json Content Post posts title:string content:string user_id:references:users

userspostshas_many:belongs_to: 关系。)

关注

mix phx.gen.json Accounts Follow follows following_id:references:users followed_id:references:users

(当用户A关注用户B时,会创建一个新的Follow条目,其中following_id指向A,followed_id指向B。)

新闻源

mix phx.gen.json Content Newsfeeditem newsfeeditems type:string, user_id:integer, content:string

现在我想查询这个东西。对我来说,获取给定用户的 Newsfeeditems 列表很简单:

进口Ecto.Query

query =
  from n in Newsfeeditem,
    where: n.user_id == ^user_id

假设我是用户 1,我正在关注用户 2、3 和 4。follows table 中有三个条目。要为这些用户获取所有相应的 newsfeeditems,查询将如下所示:

query =
  from n in Newsfeeditem,
    where: n.user1_id in [2,3,4]

我想让它动态化。这就是我迷路的地方。我想做类似这样的事情:

subquery =
  from f in Follow,
    where: f.following_id == 1,
    select: f.follower_id

query =
  from n in Newsfeeditem,
    where: n.user_id in (Repo.all(subquery))

显然这行不通,但我不确定如何正确构建这些东西。

如何通过子查询select? (注意我正在专门寻找子查询的解决方案,但如果有更好的方法加分)

Subquerys are currently not allowed in where clauses; the documentation recommends using a JOIN instead. 您的查询可以很容易地转换为 JOIN。我还没有测试过,但这应该有效:

query =
  from f in Follow,
    where: f.following_id == 1,
    join: n in Newsfeeditem,
    on: n.user_id == f.follower_id,
    select: n