使 Ecto 查询更高效

Make Ecto queries more efficient

我正在尝试查看当前用户的团队是否与传入用户的团队重叠。我有一些有用的东西,但我很好奇它是否能让我更有效率。这是我拥有的:

user_teams = from(
  t in MyApp.Team,
  left_join: a in assoc(t, :accounts),
  where: p.owner_id == ^user.id or (a.user_id == ^user.id and t.id == a.project_id)
) |> Repo.all

current_user_teams = from(
  t in MyApp.Team,
  left_join: a in assoc(t, :accounts),
  where: t.owner_id == ^current_user.id or (a.user_id == ^current_user.id and p.id == a.project_id)
) |> Repo.all

然后我将它们与以下内容进行比较:

Enum.any?(user_teams, fn(t) -> t in current_user_teams end)

同样,这符合我的需要,但似乎有更好的方法来做到这一点?

最简单的解决方案就是将这两个查询合并为一个并检查生成的查询是否 returns 有任何内容。因此,让我们完全做到这一点:

query = from t in MyApp.Team,
  left_join: a in assoc(t, :accounts),
  where: p.owner_id == ^user.id or (a.user_id == ^user.id and t.id == a.project_id),
  where: t.owner_id == ^current_user.id or (a.user_id == ^current_user.id and p.id == a.project_id),
  limit: 1,
  select: true

not is_nil(Repo.one(query))

这将模拟来自 PostgreSQL 的 SELECT EXIST (…) 查询(在 Ecto 3.0 中将有 Repo.exist?/1 函数可以做到这一点,related issue)。

重复的 where 个片段将默认 AND 编辑。