2010-02-28 51 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