10

出于性能原因,我在编写 mongoid 查询时尽可能频繁地使用only()关键字,以指定要加载的字段。

通常的怀疑是,例如,当我希望所有管理员的用户电子邮件仅用于显示目的时。

我会写:

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

我这样做是因为我的用户模型充满了很多数据,当列出一堆电子邮件时我很乐意忽略这些数据。

但是,现在让我们想象一下,我的用户是通过 Project 模型引用的,因此对于每个项目,我可以执行以下操作:project.user. 由于 mongoid 的延迟加载,当我调用引用时,我的对象用户只会被实例化(并从数据库中查询)。

但是,如果我想列出所有管理项目所有者的所有电子邮件怎么办?

我会这样写:

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

我认为你需要在这里非规范化。首先,阅读A Note on Denormalization

您可以使用 mongoid 事件自行实现非规范化,也可以使用出色的mongoid_denormalize gem。它非常直接,在实现它之后,您可以p.user_email在查询中使用或其他内容。

于 2012-05-07T19:51:23.960 回答