2010-02-28 17 views
8

¿Es posible realizar una consulta y devolver los documentos incrustados?Devolver documentos incrustados en la consulta

Actualmente, tengo:

class Post 
    include MongoMapper::Document 

    many :comments 
end 

class Comment 
    include MongoMapper::EmbeddedDocument 

    belongs_to :post 

    key :author 
    key :date 
    key :body 
end 

Aquí es una consulta que es casi allí:

Post.all("comments.date" => {"$gt" => 3.days.ago}) 

Esto devolverá todos los objetos postales, pero no los comentarios. Supongo que podría hacer algo como:

Post.all("comments.date" => {"$gt" => 3.days.ago}).map(&:comments) 

Pero esto devolvería todos los comentarios de las publicaciones. Me gustaría obtener todos los comentarios que cumplen esta condición. Quizás Comment no se debe incrustar.

Respuesta

5

Supongo que está buscando todos los comentarios más nuevos que hace tres días? Como sus Comentarios son solo documentos incrustados, no existen sin el objeto Post, por lo que no hay forma de "consultarlos" por separado (esto es en realidad un future feature of MongoDB). Sin embargo, usted puede fácilmente agregar un método de conveniencia para ayudarle a salir:

class Comment 
    include MongoMapper::EmbeddedDocument 

    def self.latest 
    Post.all(:conditions => {"comments.date" => {"$gt" => 3.days.ago}}).map{|p| p.comments}.flatten 
    end 
end 

Este método podría conseguir que todos los comentarios que se han actualizado en los últimos tres días, pero que no sería del todo en orden. Una mejor solución podría ser el uso de map/reduce a tirar de los últimos Comentarios:

class Comment 
    include MongoMapper::EmbeddedDocument 

    def self.latest 
    map = <<-JS 
    function(){ 
     this.comments.forEach(function(comment) { 
     emit(comment.created_at, comment) 
     }); 
    } 
    JS 
    r = "function(k,vals){return 1;}" 
    q = {'comments.created_at' => {'$gt' => 3.days.ago}} 

    Post.collection.map_reduce(m,r,:query => q).sort([['$natural',-1]]) 
    end 
end 

Advertencia: lo anterior es el código, no está comprobado y apenas existe como un ejemplo, pero en teoría debería devolver todos los comentarios de los últimos tres días ordenados en orden descendente.

+0

¿Crees que sería mejor incluir los comentarios en su propia colección? – vrish88

+2

Honestamente, depende del enfoque de su aplicación. Si su aplicación se trata principalmente de comentar, tal vez. Sin embargo, hay otras soluciones a considerar también. Por ejemplo, podría crear una colección limitada desnormalizada llamada "comentarios" que simplemente almacenara los últimos, por ejemplo, 100 comentarios en una colección separada. Entonces podría mostrar esa alimentación cuando sea necesario, pero mostrar la alimentación de publicación de lo contrario. Los sistemas NoSQL fomentan la experimentación en el diseño de datos, ¡encuentre lo que funciona mejor para usted! –

Cuestiones relacionadas