Elixir 如何通过ID以精确的顺序获取记录
我有一个记录ID的列表-Elixir 如何通过ID以精确的顺序获取记录,elixir,phoenix-framework,ecto,Elixir,Phoenix Framework,Ecto,我有一个记录ID的列表-[9,1,4,3] 我想从postgresql中检索记录,并希望它们按此ids列表中的顺序排列。但当我进行查询时,记录会以任意顺序返回: Ecto.Query.from(r in Record, where: r.id in [9, 1, 4, 3]) |> Repo.all() |> Enum.map(&Map.get(&1, :id)) # => [4, 9, 1, 3] 如何检索相同顺序的记录?我认为在数据库中没有任何简
[9,1,4,3]
我想从postgresql中检索记录,并希望它们按此ids列表中的顺序排列。但当我进行查询时,记录会以任意顺序返回:
Ecto.Query.from(r in Record, where: r.id in [9, 1, 4, 3])
|> Repo.all()
|> Enum.map(&Map.get(&1, :id)) # => [4, 9, 1, 3]
如何检索相同顺序的记录?我认为在数据库中没有任何简单的方法可以做到这一点,但在Elixir中有一种方法可以做到这一点:
ids = [123, 4, 1, 3, 2, 456]
posts = from(p in Post, where: p.id in ^ids, select: {p.id, p}) |> Repo.all |> Map.new
posts = for id <- ids, posts[id], do: posts[id]
posts |> Enum.map(&(&1.id)) |> IO.inspect
首先,我们构建一个
id=>post
的映射。然后,对于ids
中的每个id,如果找到了相应的Post,我们将获得相应的Post。在我的应用程序中,没有id为123或456的帖子,因此它们在中被忽略。对于,您可以使用PostgreSQL和Ecto。在您的情况下,它看起来像:
Ecto.Query.from(r in Record, where: r.id in [9, 1, 4, 3])
|> Ecto.Query.order_by([r], fragment("array_position(?, ?)", [9, 1, 4, 3], r.id)
|> Repo.all()
我会避免在数据库引擎之外处理数据。在这个简单的例子中,这不重要。但是,它可能会影响更大数据集或更复杂数据结构的性能,因为首先,您必须将结果加载到内存中,然后对其执行操作以更改顺序。如果您想在数据库级别执行此操作,那么我没有更好的主意,只能在orderby
语句idx
函数中使用case
,但这需要CREATE EXTENSION intarray
当我尝试使用^array
时,此答案不起作用,我不确定您要在哪里使用该数组。可能应该改为array
——如果看不到代码,很难猜测。这应该标记为可接受的答案,因为它是在数据库级别完成的,这是原始问题
Ecto.Query.from(r in Record, where: r.id in [9, 1, 4, 3])
|> Ecto.Query.order_by([r], fragment("array_position(?, ?)", [9, 1, 4, 3], r.id)
|> Repo.all()