Commit 21f412d31a35f0a531a6de5d5fdbd14a3dde9730

Authored by Braulio Bhavamitra
1 parent 12ce7514

Adapt search controllers to Solr

Solr uses stop words configuration on the server and not on application
level. So stop words code and tests were deleted

Do not throw 'Out of sync' exceptions when ordering with acts_as_solr.
Use the results from the database ignoring index results not present in
the database.
app/controllers/public/profile_search_controller.rb
@@ -8,11 +8,10 @@ class ProfileSearchController < PublicController @@ -8,11 +8,10 @@ class ProfileSearchController < PublicController
8 def index 8 def index
9 @q = params[:q] 9 @q = params[:q]
10 unless @q.blank? 10 unless @q.blank?
11 - @filtered_query = remove_stop_words(@q)  
12 if params[:where] == 'environment' 11 if params[:where] == 'environment'
13 redirect_to :controller => 'search', :query => @q 12 redirect_to :controller => 'search', :query => @q
14 else 13 else
15 - @results = profile.articles.published.find_by_contents(@filtered_query).paginate(:per_page => 10, :page => params[:page]) 14 + @results = profile.articles.published.find_by_contents(@q)[:results].paginate(:per_page => 10, :page => params[:page])
16 end 15 end
17 end 16 end
18 end 17 end
app/controllers/public/search_controller.rb
@@ -89,7 +89,7 @@ class SearchController < PublicController @@ -89,7 +89,7 @@ class SearchController < PublicController
89 # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop 89 # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop
90 90
91 if !@query.blank? || @region && !params[:radius].blank? 91 if !@query.blank? || @region && !params[:radius].blank?
92 - @result_ids = @noosfero_finder.find(asset, @filtered_query, calculate_find_options(asset, nil, params[:page], @product_category, @region, params[:radius], params[:year], params[:month]).merge({:limit => :all})) 92 + @result_ids = @noosfero_finder.find(asset, @query, calculate_find_options(asset, nil, params[:page], @product_category, @region, params[:radius], params[:year], params[:month]).merge({:limit => :all}))
93 end 93 end
94 94
95 end 95 end
@@ -149,7 +149,6 @@ class SearchController < PublicController @@ -149,7 +149,6 @@ class SearchController < PublicController
149 149
150 def index 150 def index
151 @query = params[:query] || '' 151 @query = params[:query] || ''
152 - @filtered_query = remove_stop_words(@query)  
153 @product_category = ProductCategory.find(params[:product_category]) if params[:product_category] 152 @product_category = ProductCategory.find(params[:product_category]) if params[:product_category]
154 153
155 @region = City.find_by_id(params[:city]) if !params[:city].blank? && params[:city] =~ /^\d+$/ 154 @region = City.find_by_id(params[:city]) if !params[:city].blank? && params[:city] =~ /^\d+$/
@@ -163,7 +162,7 @@ class SearchController < PublicController @@ -163,7 +162,7 @@ class SearchController < PublicController
163 162
164 where_to_search.select { |key,description| @searching[key] }.each do |key, description| 163 where_to_search.select { |key,description| @searching[key] }.each do |key, description|
165 @order << key 164 @order << key
166 - @results[key] = @noosfero_finder.find(key, @filtered_query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius], params[:year], params[:month])) 165 + @results[key] = @noosfero_finder.find(key, @query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius], params[:year], params[:month]))
167 @names[key] = getterm(description) 166 @names[key] = getterm(description)
168 end 167 end
169 168
app/helpers/search_helper.rb
@@ -3,21 +3,12 @@ module SearchHelper @@ -3,21 +3,12 @@ module SearchHelper
3 # FIXME remove it after search_controler refactored 3 # FIXME remove it after search_controler refactored
4 include EventsHelper 4 include EventsHelper
5 5
6 - STOP_WORDS = {  
7 - 'pt_BR' => Ferret::Analysis::FULL_PORTUGUESE_STOP_WORDS,  
8 - 'en' => Ferret::Analysis::FULL_ENGLISH_STOP_WORDS,  
9 - }  
10 -  
11 def relevance_for(hit) 6 def relevance_for(hit)
12 n = (hit.ferret_score if hit.respond_to?(:ferret_score)) 7 n = (hit.ferret_score if hit.respond_to?(:ferret_score))
13 n ||= 1.0 8 n ||= 1.0
14 (n * 100.0).round 9 (n * 100.0).round
15 end 10 end
16 11
17 - def remove_stop_words(query)  
18 - (query.downcase.scan(/"[^"]*"?|'[^']*'?|[^'"\s]+/) - (STOP_WORDS[locale] || [])).join(' ')  
19 - end  
20 -  
21 def display_results(use_map = true) 12 def display_results(use_map = true)
22 13
23 unless use_map && GoogleMaps.enabled?(environment.default_hostname) 14 unless use_map && GoogleMaps.enabled?(environment.default_hostname)
test/factories.rb
@@ -22,7 +22,7 @@ module Noosfero::Factory @@ -22,7 +22,7 @@ module Noosfero::Factory
22 end 22 end
23 end 23 end
24 if options[:search] 24 if options[:search]
25 - obj.ferret_create 25 + obj.solr_save
26 end 26 end
27 obj 27 obj
28 end 28 end
test/functional/profile_search_controller_test.rb
@@ -6,6 +6,7 @@ class ProfileSearchController; def rescue_action(e) raise e end; end @@ -6,6 +6,7 @@ class ProfileSearchController; def rescue_action(e) raise e end; end
6 6
7 class ProfileSearchControllerTest < Test::Unit::TestCase 7 class ProfileSearchControllerTest < Test::Unit::TestCase
8 def setup 8 def setup
  9 + Test::Unit::TestCase::setup
9 @controller = ProfileSearchController.new 10 @controller = ProfileSearchController.new
10 @request = ActionController::TestRequest.new 11 @request = ActionController::TestRequest.new
11 @response = ActionController::TestResponse.new 12 @response = ActionController::TestResponse.new
@@ -14,14 +15,6 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase @@ -14,14 +15,6 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase
14 end 15 end
15 attr_reader :person 16 attr_reader :person
16 17
17 - should 'filter stop words' do  
18 - @controller.expects(:locale).returns('en').at_least_once  
19 - get 'index', :profile => person.identifier, :q => 'an article about something'  
20 - assert_response :success  
21 - assert_template 'index'  
22 - assert_equal 'article something', assigns('filtered_query')  
23 - end  
24 -  
25 should 'espape xss attack' do 18 should 'espape xss attack' do
26 @controller.expects(:profile).returns(person).at_least_once 19 @controller.expects(:profile).returns(person).at_least_once
27 get 'index', :profile => person.identifier, :q => '<wslite>' 20 get 'index', :profile => person.identifier, :q => '<wslite>'
@@ -41,8 +34,8 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase @@ -41,8 +34,8 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase
41 end 34 end
42 35
43 should 'display search results' do 36 should 'display search results' do
44 - article1 = fast_create(Article, :body => '<p>Article to test profile search</p>', :profile_id => person.id)  
45 - article2 = fast_create(Article, :body => '<p>Another article to test profile search</p>', :profile_id => person.id) 37 + article1 = fast_create(Article, {:body => '<p>Article to test profile search</p>', :profile_id => person.id}, :search => true)
  38 + article2 = fast_create(Article, {:body => '<p>Another article to test profile search</p>', :profile_id => person.id}, :search => true)
46 39
47 get 'index', :profile => person.identifier, :q => 'article' 40 get 'index', :profile => person.identifier, :q => 'article'
48 41
test/functional/search_controller_test.rb
@@ -6,6 +6,7 @@ class SearchController; def rescue_action(e) raise e end; end @@ -6,6 +6,7 @@ class SearchController; def rescue_action(e) raise e end; end
6 6
7 class SearchControllerTest < Test::Unit::TestCase 7 class SearchControllerTest < Test::Unit::TestCase
8 def setup 8 def setup
  9 + Test::Unit::TestCase::setup
9 @controller = SearchController.new 10 @controller = SearchController.new
10 @request = ActionController::TestRequest.new 11 @request = ActionController::TestRequest.new
11 @response = ActionController::TestResponse.new 12 @response = ActionController::TestResponse.new
@@ -35,21 +36,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase @@ -35,21 +36,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
35 assert_valid_xhtml 36 assert_valid_xhtml
36 end 37 end
37 38
38 - should 'filter stop words' do  
39 - @controller.expects(:locale).returns('pt_BR').at_least_once  
40 - get 'index', :query => 'a carne da vaca'  
41 - assert_response :success  
42 - assert_template 'index'  
43 - assert_equal 'carne vaca', assigns('filtered_query')  
44 - end  
45 -  
46 - should 'search with filtered query' do  
47 - @controller.expects(:locale).returns('pt_BR').at_least_once  
48 - get 'index', :query => 'a carne da vaca'  
49 -  
50 - assert_equal 'carne vaca', assigns('filtered_query')  
51 - end  
52 -  
53 should 'espape xss attack' do 39 should 'espape xss attack' do
54 get 'index', :query => '<wslite>' 40 get 'index', :query => '<wslite>'
55 assert_no_tag :tag => 'wslite' 41 assert_no_tag :tag => 'wslite'
vendor/plugins/acts_as_solr/lib/parser_methods.rb
@@ -135,11 +135,10 @@ module ActsAsSolr #:nodoc: @@ -135,11 +135,10 @@ module ActsAsSolr #:nodoc:
135 135
136 # Reorders the instances keeping the order returned from Solr 136 # Reorders the instances keeping the order returned from Solr
137 def reorder(things, ids) 137 def reorder(things, ids)
138 - ordered_things = Array.new(things.size)  
139 - raise "Out of sync! Found #{ids.size} items in index, but only #{things.size} were found in database!" unless things.size == ids.size  
140 - things.each do |thing|  
141 - position = ids.index(thing.id)  
142 - ordered_things[position] = thing 138 + ordered_things = []
  139 + ids.each do |id|
  140 + thing = things.find { |t| t.id.to_s == id.to_s }
  141 + ordered_things |= [thing] if thing
143 end 142 end
144 ordered_things 143 ordered_things
145 end 144 end