2012-05-07 4 views
10

パフォーマンス上の理由から、ロードするフィールドを指定するためにmongoidクエリを書き込むときに、できるだけ頻繁にonly()というキーワードを使用します。Mongoid:オブジェクトのいくつかのフィールドだけを読み込み、参照によって怠惰に読み込む方法はありますか?

普通の容疑者は、たとえば、すべての管理者のユーザーの電子メールを表示目的でのみ使用する場合です。

私が書くでしょう:私のユーザモデルが電子メールの束を一覧表示するとき、私は喜んで無視することができ、データの多くの非常に満ちているので、

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

私はこれを行います。

しかし、今私のユーザーはProjectモデルで参照されているので、プロジェクトごとに私はできる:project.user。 mongoidの怠惰な読み込みのおかげで、私の参照を呼び出すとき、私のオブジェクトのユーザーはインスタンス化される(そしてDBから照会される)。

しかし、たとえば、すべての管理プロジェクトのオーナーのメールをすべて一覧にしたい場合はどうすればよいですか?

私はこの記述します。ここでの大きな問題は、これをやって、私は各プロジェクトのための全体のユーザーオブジェクトをロードし、かなり重い得ることができるクエリに一致するプロジェクトがたくさんある場合ということです

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

を。では、どのようにしてメールのみを読み込むのですか?

私はこれを行うことができます:p.user.only(:email).email、私は次のことができます。私は私のような何かを書くことがしたい

p.user.email 

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

しかし、これは明らかに、単純にやっての素敵な構文の目的を敗北を't。何か案は ?

アレックスは

答えて

6

Mongoidの作成者からの回答。それはまだできません。機能要求として追加されました。

+1

これはまだ実装されていますか?これにはGitHubの問題がありますか? –

+0

これはpluckコマンドで追加されました。 User.all.pluck(:id)。 @ボスコビッチへの寄付はこちらhttp://stackoverflow.com/a/9991754/1050054 –

2

私はあなたがここに非正規化する必要があると思います。まず、A Note on Denormalizationと読んでください。

mongoidイベントを使用して自己によって非正規化を実装することも、偉大なmongoid_denormalize gemを使用することもできます。それはかなりまっすぐで、それを実装した後はp.user_emailかあなたの質問に何かを使うことができます。

+0

ありがとう、それは興味深いアプローチです。私はそれを(私が知らなかったmongoid_denormalizeではなく)考慮しましたが、一般的な非正規化です。私がそれに同行しないことにした理由は、プロジェクトのユーザーメールを表示する必要性は稀であり、内部管理インターフェースで最もよく使われています。この問題は、多くのプロジェクトでページが変更され、多くのユーザー負荷がかかるという事実があります。だから、.only()は私の特定の問題を解決するだろう – Alex

関連する問題