10

only()パフォーマンス上の理由から、ロードするフィールドを指定するために、mongoidクエリを作成するときにキーワードをできるだけ頻繁に使用します。

通常の容疑者は、たとえば、表示目的でのみすべての管理者のユーザーの電子メールが必要な場合です。

私は書くだろう:

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

これを行うのは、ユーザーモデルが大量の電子メールを一覧表示するときに喜んで無視できる大量のデータでいっぱいだからです。

ただし、ここで、ユーザーがプロジェクトモデルを介して参照されていると想像してみてください。これにより、プロジェクトごとに次のことができるようになりますproject.user。mongoidの遅延読み込みのおかげで、オブジェクトユーザーは、参照を呼び出したときにのみインスタンス化されます(そしてDBから照会されます)。

しかし、たとえば、すべての管理プロジェクトの所有者のすべての電子メールを一覧表示したい場合はどうなりますか?

私はこれを書きます:

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

ここでの主な問題は、これを行うと、各プロジェクトのユーザーオブジェクト全体が読み込まれ、クエリに一致するプロジェクトが多数ある場合はかなり重くなる可能性があることです。では、どうすればメールだけをロードできますか?

私はこれを行うことができます:

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

しかし、これは明らかに、単純に実行するという優れた構文の目的を無効にします。

p.user.email 

次のようなものが書けたらいいのにと思いますp.user.only(:email).emailが、できません。何か案は ?

アレックス

4

2 に答える 2

6

Mongoidの作成者からの回答。まだできません。機能リクエストとして追加されました。

于 2012-05-09T10:56:26.750 に答える
2

ここで非正規化する必要があると思います。まず、非正規化に関する注記をお読みください。

mongoidイベントを使用して自己で非正規化を実装するか、greatmongoid_denormalizegemを使用できます。それはかなりまっすぐで、それを実装した後p.user_email、あなたはあなたのクエリで何かを使うことができました。

于 2012-05-07T19:51:23.960 に答える