【发布时间】:2022-01-10 04:07:47
【问题描述】:
是否可以仅使用纯 Ecto 查询而不是在应用程序端从数据库中获取 10 条随机记录?例如,我不想从数据库中获取所有记录,然后在 Elixir 中从它们中获取随机值(像这样):
Subscribers
|> Repo.all
|> Enum.take_random(10)
【问题讨论】:
标签: postgresql elixir ecto
是否可以仅使用纯 Ecto 查询而不是在应用程序端从数据库中获取 10 条随机记录?例如,我不想从数据库中获取所有记录,然后在 Elixir 中从它们中获取随机值(像这样):
Subscribers
|> Repo.all
|> Enum.take_random(10)
【问题讨论】:
标签: postgresql elixir ecto
Ecto 不提供用于检索记录的通用 random 函数,因为底层数据库/模式可以(并且确实)以非常不同的方式实现它。
但是,如果您知道要处理的数据库是什么,则可以使用fragment/1 和limit/3 来实现。对于postgresql,您可以将它们与RANDOM() 函数一起使用:
import Ecto.Query
query =
from Subscribers,
order_by: fragment("RANDOM()"),
limit: 10
Repo.all(query)
这相当于调用这个sql查询:
SELECT * FROM subscribers ORDER BY RANDOM() LIMIT 10
【讨论】:
import Ecto.Query)
我发现这个问题试图弄清楚如何获取具有 nil parent_task 属性的单个随机记录。
我想我会发布我的解决方案,以防它帮助任何人。
如果有人知道如何避免使用 List.first 并且只使用 Ecto 查询,我将不胜感激!
query =
from t in Subscriber,
where: is_nil(t.parent_task),
order_by: fragment("RANDOM()"),
limit: 1
Repo.all(query) |> List.first
Repo.all(Subscriber) |> Enum.filter(fn x -> is_nil(x.parent_task) end) |> Enum.random()
【讨论】:
Repo.one(query)或Repo.one!(query)代替Repo.all(query) |> List.first()