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埋め込まないほうがいいかもしれません。

4

1 に答える 1

5

3 日前より新しいすべてのコメントを探していると思いますか? コメントは単なる埋め込みドキュメントであるため、 Post オブジェクトなしでは存在しないため、個別に「クエリ」する方法はありません (これは実際には 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

この方法では、過去 3 日間に更新されたすべてのコメントを取得できますが、完全に整理されているわけではありません。より良い解決策は、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

警告: 上記は完全にテストされていないコードであり、例としてのみ存在しますが、理論的には、過去 3 日間のすべてのコメントを降順に並べ替えて返す必要があります。

于 2010-02-28T08:20:03.417 に答える