このソリューションでは、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
これをより速くしたい場合は、コメントとサブコメントにインデックスを作成する必要があります。