出于性能原因,我在编写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
这样的东西,但我不能。有什么想法吗?
亚历
答案 0 :(得分:6)
来自Mongoid的创建者的回答。这还不可能。它已被添加为功能请求。
答案 1 :(得分:2)
我认为你需要在这里进行非规范化。首先,阅读A Note on Denormalization。
你可以使用mongoid事件自我实现非规范化或使用伟大的mongoid_denormalize gem。它很直接,在实现之后,您可以在查询中使用p.user_email
或其他内容。