代码之家  ›  专栏  ›  技术社区  ›  Mark Karavan

带有Ecto的嵌套子查询

  •  1
  • Mark Karavan  · 技术社区  · 7 年前

    使用Ecto v2.2.6,Phoenix 1.3

    我有一个带有新闻提要的博客应用程序。其工作原理如下:

    • 用户可以提交帖子。
    • 用户可以跟随其他用户。
    • 当用户提交帖子时,会在Newsfeed表中添加一个项目。
    • 用户可以看到他们关注的用户提交的帖子的新闻提要。

    我想用外星生物。查询以从给定用户正在关注的用户处获取新闻提要项目列表。


    快速背景。以下是对象:

    使用者

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

    邮递

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

    ( users posts 有一个 has_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

    新鲜事

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

    现在我想查询这些东西。给我一份清单 Newsfeeditems 对于给定的用户,这很容易:

    导入Ecto。查询

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

    假设我是用户1,我在关注用户2、3和4。中有三个条目 follows 桌子要为这些用户获取所有相应的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))
    

    显然这不起作用,但我不确定如何正确地构造这些东西。

    如何通过子查询选择?( 笔记 我正在专门寻找子查询解决方案,但如果有更好的方法,可以获得额外的分数)

    1 回复  |  直到 7 年前
        1
  •  4
  •   Dogbert    7 年前

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

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