2010-12-08 10 views
23

¿cómo se recupera una matriz de IDs en Mongoid?Recuperando una matriz de identificadores en Mongoid

arr=["id1","id2"] 
User.where(:id=>arr) 

Esto se puede hacer fácilmente si está recuperando otro atributo

User.where(:nickname.in=>["kk","ll"]) 

Pero me pregunto cómo hacer esto en MongoId -> Esto debería ser una muy simple y común de operación

Respuesta

39

Recuerde que la ID se almacena como :_id y no como :id. Existe un método id ayudante, pero cuando lo hace consultas, debe utilizar :_id:

User.where(:_id.in => arr) 

A menudo me resulta útil para obtener una lista de identificadores que hacer consultas complejas, así que hacer algo como:

user_ids = User.only(:_id).where(:foo => :bar).map(&:_id) 
Post.where(:user_id.in => user_ids) 
+0

La solución anterior funciona bien cuando cantidad de usuarios es pequeña. Pero requerirá mucha memoria mientras haya miles de usuarios. – dpaluy

+0

@dpaluy tienes razón, este enfoque es solo un truco. Además, los datos pueden cambiar entre la primera y la segunda consulta, especialmente cuando hay muchos documentos. Use con precaución, o mejor aún, ¡encuentre una mejor manera! – bowsersenior

+3

La mejor manera es usar '.distinct (: _ id)' en lugar de '.map (&: _ id)'. 'distinct' funciona durante la ejecución de la consulta, que es un poco más rápido que decir a los rieles para hacer un ciclo de la matriz – Zakwan

4

El método anterior sugerido por browsersenior parece que ya no funciona, al menos para mí. Lo que hago es:

User.criteria.id(arr) 
+3

Solo una nota rápida. Con Mongoid 2.0.0 y versiones posteriores, deberá usar 'for_ids' en lugar de' id' como lo siguiente: 'User.criteria.for_ids (arr)' – bowsersenior

5

O simplemente:

arr = ['id1', 'id2', 'id3'] 
User.find(arr) 
+1

Problema anterior: si no se encuentra una sola ID, se devolverá error y no los identificadores que se encontraron. – dman

+0

'Mongoid.raise_not_found_error = false' evitará que se produzca un error en el documento no encontrado en la consulta anterior – r3bo0t

2
user_ids = User.only(:_id).where(:foo => :bar).map(&:_id) 
Post.where(:user_id.in => user_ids) 

La solución anterior funciona bien cuando cantidad de usuarios es pequeña. Pero requerirá mucha memoria mientras haya miles de usuarios.

User.only(:_id).where(:foo => :bar).map(&:_id) 

creará una lista de objetos de usuario con nulo en cada campo excepto id.

La solución (por MongoId 2,5):

User.collection.master.where(:foo => :bar).to_a.map {|o| o['_id']} 
Cuestiones relacionadas