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 8 def index
9 9 @q = params[:q]
10 10 unless @q.blank?
11   - @filtered_query = remove_stop_words(@q)
12 11 if params[:where] == 'environment'
13 12 redirect_to :controller => 'search', :query => @q
14 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 15 end
17 16 end
18 17 end
... ...
app/controllers/public/search_controller.rb
... ... @@ -89,7 +89,7 @@ class SearchController < PublicController
89 89 # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop
90 90  
91 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 93 end
94 94  
95 95 end
... ... @@ -149,7 +149,6 @@ class SearchController < PublicController
149 149  
150 150 def index
151 151 @query = params[:query] || ''
152   - @filtered_query = remove_stop_words(@query)
153 152 @product_category = ProductCategory.find(params[:product_category]) if params[:product_category]
154 153  
155 154 @region = City.find_by_id(params[:city]) if !params[:city].blank? && params[:city] =~ /^\d+$/
... ... @@ -163,7 +162,7 @@ class SearchController < PublicController
163 162  
164 163 where_to_search.select { |key,description| @searching[key] }.each do |key, description|
165 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 166 @names[key] = getterm(description)
168 167 end
169 168  
... ...
app/helpers/search_helper.rb
... ... @@ -3,21 +3,12 @@ module SearchHelper
3 3 # FIXME remove it after search_controler refactored
4 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 6 def relevance_for(hit)
12 7 n = (hit.ferret_score if hit.respond_to?(:ferret_score))
13 8 n ||= 1.0
14 9 (n * 100.0).round
15 10 end
16 11  
17   - def remove_stop_words(query)
18   - (query.downcase.scan(/"[^"]*"?|'[^']*'?|[^'"\s]+/) - (STOP_WORDS[locale] || [])).join(' ')
19   - end
20   -
21 12 def display_results(use_map = true)
22 13  
23 14 unless use_map && GoogleMaps.enabled?(environment.default_hostname)
... ...
test/factories.rb
... ... @@ -22,7 +22,7 @@ module Noosfero::Factory
22 22 end
23 23 end
24 24 if options[:search]
25   - obj.ferret_create
  25 + obj.solr_save
26 26 end
27 27 obj
28 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  
7 7 class ProfileSearchControllerTest < Test::Unit::TestCase
8 8 def setup
  9 + Test::Unit::TestCase::setup
9 10 @controller = ProfileSearchController.new
10 11 @request = ActionController::TestRequest.new
11 12 @response = ActionController::TestResponse.new
... ... @@ -14,14 +15,6 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase
14 15 end
15 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 18 should 'espape xss attack' do
26 19 @controller.expects(:profile).returns(person).at_least_once
27 20 get 'index', :profile => person.identifier, :q => '<wslite>'
... ... @@ -41,8 +34,8 @@ class ProfileSearchControllerTest &lt; Test::Unit::TestCase
41 34 end
42 35  
43 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 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  
7 7 class SearchControllerTest < Test::Unit::TestCase
8 8 def setup
  9 + Test::Unit::TestCase::setup
9 10 @controller = SearchController.new
10 11 @request = ActionController::TestRequest.new
11 12 @response = ActionController::TestResponse.new
... ... @@ -35,21 +36,6 @@ class SearchControllerTest &lt; Test::Unit::TestCase
35 36 assert_valid_xhtml
36 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 39 should 'espape xss attack' do
54 40 get 'index', :query => '<wslite>'
55 41 assert_no_tag :tag => 'wslite'
... ...
vendor/plugins/acts_as_solr/lib/parser_methods.rb
... ... @@ -135,11 +135,10 @@ module ActsAsSolr #:nodoc:
135 135  
136 136 # Reorders the instances keeping the order returned from Solr
137 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 142 end
144 143 ordered_things
145 144 end
... ...