Até agora, encontrei desta forma mas se souber de algo melhor por favor responda também...
primeiro código:
1.9.2p290 :038 > Competitor = Struct.new(:html_url, :description, :user)
1.9.2p290 :039 > time = Benchmark.measure do
1.9.2p290 :040 > competitors = []
1.9.2p290 :041?>
1.9.2p290 :042 > User.all.map do |user|
1.9.2p290 :043 > user.watchlists.all.map do |wl|
1.9.2p290 :044 > if wl.tags_array == ["ruby", "web", "framework"]
1.9.2p290 :045?> competitors << Competitor.new(wl.html_url, wl.description, wl.user.nickname)
1.9.2p290 :046?> end
1.9.2p290 :047?> end
1.9.2p290 :048?> end
1.9.2p290 :049?> end
MONGODB (34ms) heroku_app1707530['users'].find({})
MONGODB [DEBUG] cursor.refresh() for cursor 2492208785546818168
MONGODB [DEBUG] cursor.refresh() for cursor 2492208785546818168
=> 1.390000 0.010000 1.400000 ( 1.400842)
1.9.2p290 :050 >
vs. segundo código:
1.9.2p290 :049 > Competitor = Struct.new(:html_url, :description, :user)
1.9.2p290 :050 > time = Benchmark.measure do
1.9.2p290 :051 > competitors = []
1.9.2p290 :052?>
1.9.2p290 :053 > User.where('watchlists.tags_array' => %w[ruby web framework]).only(:nickname, :watchlists).each do |u|
1.9.2p290 :054 > u.watchlists.where(:tags_array => %w[ruby web framework]).each do |wl|
1.9.2p290 :055 > competitors << Competitor.new(wl.html_url, wl.description, u.nickname)
1.9.2p290 :056?> end
1.9.2p290 :057?> end
1.9.2p290 :058?> end
MONGODB (185ms) heroku_app1707530['users'].find({"watchlists.tags_array"=>["ruby", "web", "framework"]}, {:_type=>1, :nickname=>1, :watchlists=>1})
MONGODB [DEBUG] cursor.refresh() for cursor 2195378613558492020
=> 0.440000 0.000000 0.440000 ( 0.456714)
1.9.2p290 :059 >
mas melhor ainda:
primeiro código:
1.9.2p290 :157 > Competitor = Struct.new(:html_url, :description, :user)
1.9.2p290 :158 > competitors = []
=> []
1.9.2p290 :159 > Benchmark.bm(10) do |x|
1.9.2p290 :160 > x.report("first:") do
1.9.2p290 :161 > User.all.map do |user|
1.9.2p290 :162 > user.watchlists.all.map do |wl|
1.9.2p290 :163 > if wl.tags_array == ["ruby", "web", "framework"]
1.9.2p290 :164?> competitors << Competitor.new(wl.html_url, wl.description, wl.user.nickname)
1.9.2p290 :165?> end
1.9.2p290 :166?> end
1.9.2p290 :167?> end
1.9.2p290 :168?> end
1.9.2p290 :169?> x.report("second:") do
1.9.2p290 :170 > User.all.map do |user|
1.9.2p290 :171 > user.watchlists.all.map do |wl|
1.9.2p290 :172 > if wl.tags_array == ["ruby", "web", "framework"]
1.9.2p290 :173?> competitors << Competitor.new(wl.html_url, wl.description, wl.user.nickname)
1.9.2p290 :174?> end
1.9.2p290 :175?> end
1.9.2p290 :176?> end
1.9.2p290 :177?> end
1.9.2p290 :178?> x.report("third:") do
1.9.2p290 :179 > User.all.map do |user|
1.9.2p290 :180 > user.watchlists.all.map do |wl|
1.9.2p290 :181 > if wl.tags_array == ["ruby", "web", "framework"]
1.9.2p290 :182?> competitors << Competitor.new(wl.html_url, wl.description, wl.user.nickname)
1.9.2p290 :183?> end
1.9.2p290 :184?> end
1.9.2p290 :185?> end
1.9.2p290 :186?> end
1.9.2p290 :187?> end
user system total real
first: MONGODB (30ms) heroku_app1707530['users'].find({})
MONGODB [DEBUG] cursor.refresh() for cursor 6320857008182747446
MONGODB [DEBUG] cursor.refresh() for cursor 6320857008182747446
1.460000 0.010000 1.470000 ( 1.475545)
second: MONGODB (24ms) heroku_app1707530['users'].find({})
MONGODB [DEBUG] cursor.refresh() for cursor 8580701579081246457
MONGODB [DEBUG] cursor.refresh() for cursor 8580701579081246457
1.470000 0.010000 1.480000 ( 1.494812)
third: MONGODB (24ms) heroku_app1707530['users'].find({})
MONGODB [DEBUG] cursor.refresh() for cursor 6472818135140756688
MONGODB [DEBUG] cursor.refresh() for cursor 6472818135140756688
1.490000 0.010000 1.500000 ( 1.505000)
=> true
1.9.2p290 :188 >
vs. segundo código:
1.9.2p290 :065 > Competitor = Struct.new(:html_url, :description, :user)
1.9.2p290 :066 > competitors = []
=> []
1.9.2p290 :067 > Benchmark.bm(10) do |x|
1.9.2p290 :068 > x.report("first:") {User.where('watchlists.tags_array' => %w[ruby web framework]).only(:nickname, :watchlists).each{|u|u.watchlists.where(:tags_array => %w[ruby web framework]).each{|wl|competitors << Competitor.new(wl.html_url, wl.description, u.nickname)}}}
1.9.2p290 :069?> x.report("second:") {User.where('watchlists.tags_array' => %w[ruby web framework]).only(:nickname, :watchlists).each{|u|u.watchlists.where(:tags_array => %w[ruby web framework]).each{|wl|competitors << Competitor.new(wl.html_url, wl.description, u.nickname)}}}
1.9.2p290 :070?> x.report("third:") {User.where('watchlists.tags_array' => %w[ruby web framework]).only(:nickname, :watchlists).each{|u|u.watchlists.where(:tags_array => %w[ruby web framework]).each{|wl|competitors << Competitor.new(wl.html_url, wl.description, u.nickname)}}}
1.9.2p290 :071?> end
user system total real
first: MONGODB (163ms) heroku_app1707530['users'].find({"watchlists.tags_array"=>["ruby", "web", "framework"]}, {:_type=>1, :nickname=>1, :watchlists=>1})
MONGODB [DEBUG] cursor.refresh() for cursor 7239021952645827000
0.330000 0.000000 0.330000 ( 0.380199)
second: MONGODB (164ms) heroku_app1707530['users'].find({"watchlists.tags_array"=>["ruby", "web", "framework"]}, {:_type=>1, :nickname=>1, :watchlists=>1})
MONGODB [DEBUG] cursor.refresh() for cursor 4816095738351422260
0.320000 0.010000 0.330000 ( 0.381196)
third: MONGODB (125ms) heroku_app1707530['users'].find({"watchlists.tags_array"=>["ruby", "web", "framework"]}, {:_type=>1, :nickname=>1, :watchlists=>1})
MONGODB [DEBUG] cursor.refresh() for cursor 5014359782446173361
0.390000 0.010000 0.400000 ( 0.397241)
=> true
1.9.2p290 :072 >
então o segundo código resulta muito mais rápido e consome menos CPU ..., graças a rubish para o "segundo código"