2012-05-07 18 views
10

Vì lý do hiệu suất, tôi sử dụng thường xuyên nhất có thể từ khóa only() khi viết truy vấn mongoid để chỉ định các trường tôi muốn tải.Mongoid: Làm thế nào để tải chỉ một số lĩnh vực của một đối tượng bạn tải lười biếng thông qua tham khảo?

Nghi ngờ thông thường, chẳng hạn như khi tôi muốn email của tất cả quản trị viên chỉ sử dụng cho mục đích hiển thị.

Tôi sẽ viết:

User.where(:groups => :admins).only(:email).each do |u| 
puts u.email 
end 

Tôi làm điều này vì mô hình của tôi sử dụng là khá đầy đủ của rất nhiều dữ liệu mà tôi sẵn sàng có thể bỏ qua khi liệt kê một loạt các email.

Tuy nhiên, bây giờ hãy tưởng tượng, người dùng của tôi được tham chiếu qua mô hình Dự án, để cho mỗi dự án tôi có thể làm: project.user. Nhờ tải lười biếng của Mongoid, người dùng đối tượng của tôi sẽ chỉ nhận được instantiated (và truy vấn từ DB) khi tôi gọi khi tham chiếu.

Nhưng nếu tôi muốn liệt kê tất cả email của chủ sở hữu của tất cả dự án quản trị thì sao?

Tôi sẽ viết này:

Project.where(:admin_type => true).each do |p| 
    puts p.user.email 
end 

Vấn đề chính ở đây là làm điều này, tôi tải toàn bộ đối tượng người sử dụng đối với từng dự án, và nếu có rất nhiều dự án phù hợp với truy vấn có thể nhận được khá nặng . Vậy làm thế nào để tôi chỉ tải các email?

tôi có thể làm điều này:

User.where(:_id => p.user_id).only(:email).first.email 

Nhưng điều này rõ ràng là đánh bại mục đích của cú pháp tốt đẹp của đơn giản là thực hiện:

p.user.email 

Tôi ước gì tôi có thể viết một cái gì đó như: p.user.only(:email).email, nhưng tôi có thể 't. Ý tưởng nào?

Alex

Trả lời

6

Trả lời từ tác giả của Mongoid. Nó không thể được nêu ra. Nó đã được thêm vào làm yêu cầu tính năng.

+1

Điều này đã được triển khai chưa? Có một vấn đề trên GitHub tồn tại cho điều này? –

+0

Điều này đã được thêm vào với lệnh nhổ. User.all.pluck (: id). Ghi có vào @bosskovic tại đây http://stackoverflow.com/a/9991754/1050054 –

2

Tôi nghĩ bạn cần chuẩn hóa ở đây. Trước tiên, hãy đọc A Note on Denormalization.

Bạn có thể thực hiện chuẩn hóa bằng cách tự sử dụng các sự kiện mongoid hoặc sử dụng đá quý mongoid_denormalize tuyệt vời. Nó khá thẳng và sau khi thực hiện nó, bạn có thể sử dụng p.user_email hoặc một cái gì đó trong các truy vấn của bạn.

+0

Cảm ơn, đó là một cách tiếp cận thú vị. Tôi đã xem xét nó (không phải với mongoid_denormalize mà tôi không biết), nhưng nói chung không chuẩn hóa. Lý do tại sao tôi quyết định không đi với nó, là nhu cầu hiển thị email người dùng của dự án là hiếm và được sử dụng nhiều nhất trong giao diện quản trị nội bộ. Vấn đề đi kèm với thực tế là nó được phân trang với rất nhiều dự án, có đòi hỏi rất nhiều tải của người dùng. Đó là lý do tại sao một .only() sẽ giải quyết vấn đề cụ thể của tôi – Alex