2010-02-28 47 views
8

是否可以執行查詢並返回嵌入的文檔?在查詢中返回嵌入的文檔

目前,我有:

class Post 
    include MongoMapper::Document 

    many :comments 
end 

class Comment 
    include MongoMapper::EmbeddedDocument 

    belongs_to :post 

    key :author 
    key :date 
    key :body 
end 

這裏是一個查詢,幾乎有:

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

這將返回所有對象後但沒有評論。我想我可以這樣做:

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

但是,這將返回所有帖子的評論。我想要獲得滿足此條件的所有評論。也許不應該嵌入Comment

回答

5

我假設你正在尋找比三天前更新的評論嗎?由於您的評論只是嵌入式文檔,因此它們不存在沒有Post對象,因此無法單獨「查詢」它們(實際上這是一個future feature of MongoDB)。然而,你可以很容易地添加一個方便的方法來幫助你:

class Comment 
    include MongoMapper::EmbeddedDocument 

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

這種方法會得到大家已在過去三天已經更新的意見,但他們不會完全是爲了。一個更好的解決辦法可能是使用的Map/Reduce拉的最新評論:

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 

警告:上面是完全未經測試的代碼,只是存在作爲一個例子,但理論上應該返回從排序的最後三天所有評論按降序排列。

+0

你認爲將評論放入自己的收藏會更好嗎? – vrish88 2010-02-28 22:50:19

+2

老實說這取決於你的應用程序的重點。如果你的應用主要是關於評論,也許。但是,還有其他解決方案需要考慮。例如,您可以創建一個名爲「評論」的非標準化上限集合,將最新的哦,100個左右的評論存儲在單獨的集合中。然後,您可以在必要時顯示該Feed,但是否則顯示Post郵件。 NoSQL系統鼓勵在數據設計中進行實驗,找到最適合您的方式! – 2010-03-02 08:58:30