В чем разница между извлечением и сбором в Rails?

Вот два примера кода.

Первый с collect:

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

Второй с pluck:

User.first.gifts.pluck(:id)

Есть ли между ними разница в производительности или еще в чем-то?


person Mohit Jain    schedule 29.08.2012    source источник


Ответы (4)


pluck находится на уровне db. Он будет запрашивать только конкретное поле. см. это.

Когда вы делаете:

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

У вас есть объекты со всеми загруженными полями, и вы просто получаете id благодаря методу, основанному на Enumerable.

So:

  • если вам только нужен id с Rails 4, используйте ids: User.first.gifts.ids

  • если вам только нужны некоторые поля с Rails 4, используйте pluck: User.first.gifts.pluck(:id, :name, ...)

  • если вам только нужно одно поле с Rails 3, используйте pluck: User.first.gifts.pluck(:id)

  • если вам нужны все поля, используйте collect

  • если вам нужны некоторые поля с Rails 4, по-прежнему используйте pluck

  • если вам нужны некоторые поля с Rails 3, используйте selectи collect

person apneadiving    schedule 29.08.2012
comment
если вам нужны какие-то поля, используйте selectand collect — нельзя ли просто использовать pluck с несколькими атрибутами, например pluck(:id, :name)? - person Alexander; 10.12.2014
comment
@AlexPopov — Rails 4+ поддерживает pluckобъединение нескольких полей, а Rails 3 — нет, если только вы не используете Обходной путь Райана Лефевра - person marksiemers; 27.03.2015
comment
В Rails 4, если вам только нужен id, используйте .ids Ref doc: api.rubyonrails.org/classes/ActiveRecord/ - person Ivan Chau; 29.03.2015

да. Согласно руководствам по Rails, pluck напрямую преобразует результат базы данных в array без создания ActiveRecord объектов. . Это означает более высокую производительность для больших или часто выполняемых запросов.

В дополнение к ответу @apneadiving, pluck может принимать как одно, так и несколько имен столбцов в качестве аргумента:

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

Основное и главное отличие состоит в том, что Pluck применяется на уровне БД и собирает все данные, а затем возвращает запись вам, когда вам нужно, чтобы все записи использовали сбор, а когда мало полей, используйте pluck

person Thorin    schedule 04.05.2016

Если есть случай, когда вы используете несколько атрибутов извлеченной записи. В таких случаях вы должны использовать pluck .

User.collect(&:email)

В приведенном выше примере, если вам нужен только атрибут электронной почты, вы тратите память и время. Поскольку он будет извлекать все столбцы из пользовательской таблицы в базе данных, выделяет память для каждого атрибута (включая атрибуты, которые вы никогда не будете использовать).

ПРИМЕЧАНИЕ. pluck не возвращает ActiveRecord_Relation пользователя.

person Chimed Palden    schedule 16.01.2019