在Rails中,pluck和collect有什么区别?

141

这里有两段示例代码。

第一段使用了 collect

User.first.gifts.collect(&:id)

使用pluck的第二个方法:

User.first.gifts.pluck(:id)

它们在性能或其他方面有任何区别吗?

6个回答

253
pluck 是在数据库层面上执行的。它只会查询特定的字段。请参考这里
当你使用以下代码时:
 User.first.gifts.collect(&:id)

你有一些包含所有字段的对象,只需要通过基于 Enumerable 的方法获取 id

因此:

  • 如果你在 Rails 4 中仅仅需要id,请使用idsUser.first.gifts.ids

  • 如果你在 Rails 4 中仅仅需要一些字段,请使用pluckUser.first.gifts.pluck(:id, :name, ...)

  • 如果你在 Rails 3 中仅仅需要一个字段,请使用pluckUser.first.gifts.pluck(:id)

  • 如果你需要全部字段,请使用collect

  • 如果你在 Rails 4 中需要一些字段,请仍然使用pluck

  • 如果你在 Rails 3 中需要一些字段,请使用selectcollect


如果您需要一些字段,可以使用select和collect。难道您不能使用pluck与多个属性一样,例如pluck(:id,:name)吗? - Alexander Popov
@AlexPopov - Rails 4+支持从多个字段中pluck数据,而Rails 3则不支持,除非你使用Ryan Lefevre的解决方法 - marksiemers
3
在Rails 4中,如果你只需要id,可以使用.ids。参考文档:http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-ids - Ivan Chau

36

是的。根据Rails指南中的说明pluck将数据库结果直接转换为一个数组,而不构建ActiveRecord对象。这意味着对于大型或经常运行的查询,性能更好。

除了@apneadiving的答案外,pluck还可以将单个和多个列名作为参数:

Client.pluck(:id, :name)
# SELECT clients.id, clients.name FROM clients
# => [[1, 'David'], [2, 'Jeremy'], [3, 'Jose']]

4
基本的区别是Pluck应用在数据库级别,而collect获取所有数据,然后在需要时将记录返回给您。当您需要所有记录时,请使用collect,当只需要少数字段时,请使用pluck。

4

虽然来晚了,但如果您想要更深入的提取,可以使用includes

User.all.includes(:groups).pluck("users.id", "users.name", "groups.id", "groups.name")

这会导致一个更大的数组,比如:
[
  [12, "Sam", 4, "FriendsRUs"],
  ...
]

3
如果你只需要使用检索记录中的几个属性,那么就可以使用pluck
User.collect(&:email)

在上面的例子中,如果您只需要电子邮件属性,则会浪费内存和时间。因为它将从数据库中检索用户表中的所有列,为每个属性分配内存(包括您永远不会使用的属性)。
注意:pluck不会返回用户的ActiveRecord_Relation。

1
主要区别在于collect会加载数据库中的所有属性,而pluck只会加载你指定的属性。比如说,当你执行以下代码时:
User.all.collect(&:id)

这将在内存中加载所有用户记录的属性并返回其ID。当您执行以下操作时:

User.all.pluck(:id)

这样只加载 id 到内存中,所以在你只需要访问少量属性的情况下更加高效。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接