1

ドキュメントに埋め込まれている深さに関係なく、自分の条件に一致するすべてのドキュメントを見つけるにはどうすればよいですか?

*recursively_embeds_many* を使用するモデルがあるとします。たとえば、返信できるコメントです。返信には、別の返信などがあります。

class Comment
  include Mongoid::Document
  field :content, type: String
  recursively_embeds_many # this makes comment.child_comments available
end

したがって、構造は基本的に次のとおりです。

  • コメント
    • コンテンツ (文字列)
    • コメント (コメントのリスト)

contentが "foo" に等しいすべての Comment ドキュメントを照会するにはどうすればよいですか?

4

1 に答える 1

3

このソリューションでは、Mongodb ドット表記クエリを と組み合わせて使用​​し$orて、関連するコメントを取得し、それらをトラバースします。最大再帰レベルを指定する必要があります。

ライブプロダクションでは使用しないでください。あなたがデータベースをクラッシュさせたとしても、私は責任を負いたくありません:P

# app/models/comment.rb
class Comment
  include Mongoid::Document
  field :content, type: String
  recursively_embeds_many # this makes comment.child_comments available

  # 'n' is the maximum level of recursion to check.
  def self.each_matching_comment(n, q, &block)
    queries = 0.upto(n).collect { |l| level_n_query(l, q) }
    Comment.or(*queries).each { |c| c.each_matching_subcomment(q, &block) }
  end

  def self.level_n_query(n, q)
    key = (['child_comments'] * n).join('.') + 'content'
    return {key => q}
  end

  # recursive, returns array of all subcomments that match q including self
  def each_matching_subcomment(q, &block)
    yield self if self.content == q
    self.child_comments.each { |c| c.each_matching_subcomment(q, &block) }
  end
end

# hits each comment/subcomment up to level 10 with matching content once
Comment.each_matching_comment(10, 'content to match') do |comment|
  puts comment.id
end

これをより速くしたい場合は、コメントとサブコメントにインデックスを作成する必要があります。

于 2013-01-18T03:52:27.050 に答える