อะไรคือความแตกต่างระหว่างถอนขนและรวบรวมใน Rails?


123

นี่คือรหัสตัวอย่างสองรหัส

คนแรกกับcollect:

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

อันที่สองกับpluck:

User.first.gifts.pluck(:id)

มีความแตกต่างระหว่างประสิทธิภาพหรืออย่างอื่นหรือไม่?

คำตอบ:


230

pluckอยู่ในระดับฐานข้อมูล มันจะสอบถามเฉพาะฟิลด์ใดฟิลด์หนึ่ง เห็นนี้

เมื่อคุณทำ:

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

คุณมีวัตถุที่โหลดทุกช่องและคุณจะได้รับไฟล์ idขอบคุณจากวิธีการที่อิงจาก Enumerable

ดังนั้น:

  • หากคุณต้องการเพียงid Rails 4 ให้ใช้ids:User.first.gifts.ids

  • หากคุณต้องการเพียงบางฟิลด์ที่มี Rails 4 ให้ใช้pluck:User.first.gifts.pluck(:id, :name, ...)

  • ถ้าคุณเพียงต้องการข้อมูลหนึ่งที่มีทางรถไฟที่ 3 การใช้งานpluck:User.first.gifts.pluck(:id)

  • หากคุณต้องการทุกช่องให้ใช้collect

  • หากคุณต้องการบางฟิลด์ที่มี Rails 4 ให้ใช้ไฟล์ pluck

  • หากคุณต้องการบางฟิลด์ที่มี Rails 3 ให้ใช้selectและcollect


"ถ้าคุณต้องการบางช่องให้ใช้ selectand collect" - คุณใช้pluckกับหลายแอตทริบิวต์pluck(:id, :name)ไม่ได้หรือ?
Alexander

@AlexPopov - Rails 4+ รองรับการป้อนpluckข้อมูลหลายช่อง Rails 3 ไม่ทำเว้นแต่คุณจะใช้วิธีแก้ปัญหาของ Ryan Lefevre
แม่นปืน

3
ใน Rails 4 หากคุณต้องการเพียงอย่างเดียวให้idใช้.idsRef doc: api.rubyonrails.org/classes/ActiveRecord/…
Ivan Chau

30

ใช่. ตามคำแนะนำของทางรถไฟ , pluckโดยตรงแปลงผลฐานข้อมูลเป็นarrayโดยไม่มีการสร้างActiveRecordวัตถุ ซึ่งหมายถึงประสิทธิภาพที่ดีขึ้นสำหรับแบบสอบถามขนาดใหญ่หรือที่เรียกใช้บ่อย

นอกจากคำตอบของ @ apneadiving แล้วpluckยังสามารถใช้ชื่อคอลัมน์เดียวและหลายคอลัมน์เป็นอาร์กิวเมนต์ได้:

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

3

ความแตกต่างพื้นฐานและหลักคือ Pluck ใช้กับระดับฐานข้อมูลและรวบรวมรับข้อมูลทั้งหมดจากนั้นส่งคืนบันทึกให้คุณเมื่อคุณต้องการบันทึกทั้งหมดใช้การรวบรวมและเมื่อไม่กี่ฟิลด์ให้ใช้การถอน


2

หากมีบางกรณีที่คุณกำลังใช้แอตทริบิวต์เพียงไม่กี่รายการของเรกคอร์ดที่ดึงมา pluckในกรณีดังกล่าวที่คุณควรใช้

User.collect(&:email)

ในตัวอย่างข้างต้นหากคุณต้องการเพียงแอตทริบิวต์อีเมลมากกว่าที่คุณจะเสียหน่วยความจำและเวลา เนื่องจากจะดึงข้อมูลคอลัมน์ทั้งหมดจากตารางผู้ใช้ในฐานข้อมูลจัดสรรหน่วยความจำสำหรับแต่ละแอตทริบิวต์ (รวมถึงแอตทริบิวต์ที่คุณจะไม่ใช้)

หมายเหตุ: pluckไม่ส่งคืน ActiveRecord_Relation ของผู้ใช้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.