2010-02-28 18 views
8

È possibile eseguire una query e restituire i documenti incorporati?Restituisci documenti incorporati nella query

Attualmente, ho:

class Post 
    include MongoMapper::Document 

    many :comments 
end 

class Comment 
    include MongoMapper::EmbeddedDocument 

    belongs_to :post 

    key :author 
    key :date 
    key :body 
end 

Ecco una domanda che è quasi arrivati:

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

Ciò restituirà tutti gli oggetti post, ma non i commenti. Immagino di poter fare qualcosa del tipo:

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

Ma questo restituirebbe tutti i commenti dai post. Mi piacerebbe avere tutti i commenti che hanno incontrato questa condizione. Forse Comment non dovrebbe essere incorporato.

risposta

5

Immagino che tu stia cercando tutti i commenti più nuovi di tre giorni fa? Poiché i tuoi commenti sono solo documenti incorporati, non esistono senza l'oggetto Post, quindi non c'è modo di "interrogarli" separatamente (questo è in realtà un future feature of MongoDB). Tuttavia, si potrebbe facilmente aggiungere un metodo comodo per aiutarti:

class Comment 
    include MongoMapper::EmbeddedDocument 

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

Questo metodo si otterrebbe tutti i commenti che sono stati aggiornati negli ultimi tre giorni, ma non sarebbe del tutto in ordine. Una soluzione migliore potrebbe essere quella di utilizzare Map/Reduce di tirare i commenti più recenti:

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 

Caveat: Quanto sopra è codice completamente testato e solo esiste come un esempio, ma teoricamente dovrebbe restituire tutti i commenti degli ultimi tre giorni ordinati in ordine decrescente

+0

Pensi che sarebbe meglio inserire i commenti nella propria collezione? – vrish88

+2

Onestamente dipende dalla messa a fuoco della tua app. Se la tua app riguarda principalmente i commenti, forse. Tuttavia, ci sono anche altre soluzioni da considerare. Ad esempio, è possibile creare una raccolta limitata de-normalizzata denominata "commenti" che ha semplicemente memorizzato gli ultimi, oh, 100 o più commenti in una raccolta separata. Quindi è possibile visualizzare tale feed quando necessario, ma visualizzare altrimenti il ​​feed Post. I sistemi NoSQL incoraggiano la sperimentazione nella progettazione dei dati, trova ciò che funziona meglio per te! –

Problemi correlati