2012-05-07 6 views
10

Por razones de rendimiento, utilizo la palabra clave only() con la mayor frecuencia posible cuando escribo una consulta mongoid para especificar los campos que deseo cargar.Mongoid: ¿Cómo cargar solo algunos campos de un objeto que la carga lenta como referencia?

El sospechoso habitual es, por ejemplo, cuando quiero el correo electrónico de todos mis administradores para un usuario solo con fines de visualización.

que iba a escribir:

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

hago esto porque mi modelo de usuario son bastante llena de una gran cantidad de datos que puedo ignorar alegremente al enumerar un montón de mensajes de correo electrónico.

Sin embargo, imaginemos ahora que mis usuarios están referenciados a través de un modelo de proyecto, de modo que para cada proyecto puedo hacer: project.user. Gracias a la carga diferida de mongoid, mi usuario de objeto solo será instanciado (y consultado desde el DB) cuando llamo a la referencia.

Pero, ¿qué sucede si quiero enumerar todos los correos electrónicos del propietario de todos los proyectos administrativos, por ejemplo?

que iba a escribir esto:

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

El principal problema aquí es que al hacer esto, se carga todo el objeto de usuario para cada uno de los proyectos, y si hay un montón de proyectos que concuerden con la consulta que podría ser bastante pesada . Entonces, ¿cómo cargo solo los correos electrónicos?

que podía hacer esto:

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

Pero esto, evidentemente contrario al propósito de la buena sintaxis del simple hecho de hacer:

p.user.email 

Me gustaría poder escribir algo como: p.user.only(:email).email, pero no puedo 't. Algunas ideas ?

Alex

Respuesta

6

Respuesta del creador de Mongoid. No es posible todavía Se ha agregado como solicitud de funciones.

+1

¿Se ha implementado esto todavía? ¿Existe un problema en GitHub para esto? –

+0

Esto se ha agregado con el comando desplumar. User.all.pluck (: id). Gracias a @bosskovic aquí http://stackoverflow.com/a/9991754/1050054 –

2

Creo que necesita para desnormalizar aquí. Antes que nada, lea A Note on Denormalization.

Puede implementar la desnormalización usando eventos mongoid o usar la gran gema mongoid_denormalize. Es bastante directo y después de implementarlo puede usar p.user_email o algo en sus consultas.

+0

Gracias, ese es un enfoque interesante. Lo había considerado (no con mongoid_denormalize que no sabía), sino desnormalización general. La razón por la que decidí no aceptarlo es porque la necesidad de mostrar el correo electrónico del usuario del proyecto es rara y la más utilizada en una interfaz de administración interna. El problema viene con el hecho de que está paginado con muchos proyectos, que requieren mucha carga de usuario. ¿Cuál es el motivo por el cual un .only() resolvería mi problema particular – Alex

Cuestiones relacionadas