【问题标题】:Rails: uniq vs. distinctRails:uniq vs. distinct
【发布时间】:2017-01-27 06:35:38
【问题描述】:

谁能简单解释一下uniqdistinct这两种方法在使用上的区别?

我已经看到两者在相似的上下文中使用,但区别对我来说不是很清楚。

【问题讨论】:

    标签: ruby-on-rails activerecord


    【解决方案1】:

    Rails 查询类似于数组,因此.uniq 产生与.distinct 相同的结果,但是

    • .distinct是sql查询方法
    • .uniq是数组方法

    注意:在 Rails 5+ 中,Relation#uniq 已弃用,建议改用Relation#distinct。 见http://edgeguides.rubyonrails.org/5_0_release_notes.html#active-record-deprecations

    提示

    在调用.uniq/.distinct 之前使用.includes 可以减慢加速您的应用,因为

    • uniq 不会产生额外的 sql 查询
    • distinct 可以

    但是两个结果都是一样的

    例子:

    users = User.includes(:posts)
    puts users
    # First sql query for includes
    
    users.uniq
    # No sql query! (here you speed up you app)
    users.distinct
    # Second distinct sql query! (here you slow down your app)
    

    这对于制作高性能应用程序很有用

    提示

    同样适用

    • .size vs .count;
    • present?.exists?
    • mappluck

    【讨论】:

    • 感谢您的回答。我有一个问题:它不取决于数据库返回的行数吗?如果您有大量结果而不是少量行,那么 db 的性能可能比 ruby​​ 更好?
    • @GLaDOS 是的,rails 应用程序就像一座建筑物:一楼有 sql,二楼有业务逻辑,最后一层有用户的视图。 1)如果用户不需要任何数据,我们不应该将数据从一楼提升到最后。所以这意味着我们不应该在 sql 层上获取数据,而不是在 rails one 上提升它(所以使用.limit(25) 方法而不是.first(25))。 2)如果我们错过了一楼的任何数据。跑回一楼从sql中获取额外数据效率不高。所以在这种情况下使用.includes(:comments)。等等
    【解决方案2】:

    Rails 5.1 已从 Activerecord Relation 中删除了 uniq 方法并添加了 distinct 方法...

    • 如果您将 uniq 与查询一起使用,它只会将 Activerecord 关系转换为 Array 类...
    • 如果你在那里添加了 uniq,你就不能有查询链......(即你不能做 User.active.uniq.subscribed 它会抛出错误undefined method subscribed for Array
    • 如果您的数据库很大,并且您只想获取所需的不同条目,最好使用具有 Activerecord 关系查询的 distinct 方法...

    【讨论】:

    【解决方案3】:

    来自documentation

    uniq(value = true)

    别名ActiveRecord::QueryMethods#distinct

    【讨论】:

    【解决方案4】:

    它不能完全回答你的问题,但我知道的是:

    如果我们考虑 ActiveRecord 上下文,那么 uniq 只是 distinct 的别名。两者都可以删除查询结果集上的重复项(您可以说最多一级)。

    array 上下文中,uniq 非常强大,即使元素是嵌套的,它也会删除重复项。例如

    arr = [["first"], ["second"], ["first"]]
    

    如果我们这样做了

    arr.uniq
    

    答案是:[["first"], ["second"]]

    因此,即使元素是块,它也会深入并删除重复项。

    希望它在某些方面对您有所帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-12
      • 1970-01-01
      • 1970-01-01
      • 2012-12-24
      相关资源
      最近更新 更多