【问题标题】:Fetch random records from Ecto database从 Ecto 数据库中获取随机记录
【发布时间】:2022-01-10 04:07:47
【问题描述】:

是否可以仅使用纯 Ecto 查询而不是在应用程序端从数据库中获取 10 条随机记录?例如,我不想从数据库中获取所有记录,然后在 Elixir 中从它们中获取随机值(像这样):

Subscribers
|> Repo.all
|> Enum.take_random(10)

【问题讨论】:

    标签: postgresql elixir ecto


    【解决方案1】:

    Ecto 不提供用于检索记录的通用 random 函数,因为底层数据库/模式可以(并且确实)以非常不同的方式实现它。

    但是,如果您知道要处理的数据库是什么,则可以使用fragment/1 和limit/3 来实现。对于,您可以将它们与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)
    【解决方案2】:

    我发现这个问题试图弄清楚如何获取具有 nil parent_task 属性的单个随机记录。

    我想我会发布我的解决方案,以防它帮助任何人。

    解决方案 1

    如果有人知道如何避免使用 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
    

    解决方案 2

    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()
    猜你喜欢
    • 2012-04-09
    • 2018-07-20
    • 2012-04-13
    • 2011-01-27
    • 2011-04-07
    • 2017-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多