Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir 如何通过ID以精确的顺序获取记录_Elixir_Phoenix Framework_Ecto - Fatal编程技术网

Elixir 如何通过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] 如何检索相同顺序的记录?我认为在数据库中没有任何简

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

如何检索相同顺序的记录?

我认为在数据库中没有任何简单的方法可以做到这一点,但在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()