sunspot_rails 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -11,6 +11,7 @@ module Sunspot #:nodoc:
11
11
  # port: 8982
12
12
  # min_memory: 512M
13
13
  # max_memory: 1G
14
+ # solr_jar: /some/path/solr15/start.jar
14
15
  # test:
15
16
  # solr:
16
17
  # hostname: localhost
@@ -82,7 +83,7 @@ module Sunspot #:nodoc:
82
83
  # String:: host name
83
84
  #
84
85
  def master_hostname
85
- @master_hostname ||= (user_configuration_from_key('solr', 'master_hostname') || hostname)
86
+ @master_hostname ||= (user_configuration_from_key('master_solr', 'hostname') || hostname)
86
87
  end
87
88
 
88
89
  #
@@ -94,7 +95,7 @@ module Sunspot #:nodoc:
94
95
  # Integer:: port
95
96
  #
96
97
  def master_port
97
- @master_port ||= (user_configuration_from_key('solr', 'master_port') || port).to_i
98
+ @master_port ||= (user_configuration_from_key('master_solr', 'port') || port).to_i
98
99
  end
99
100
 
100
101
  #
@@ -106,7 +107,7 @@ module Sunspot #:nodoc:
106
107
  # String:: path
107
108
  #
108
109
  def master_path
109
- @master_path ||= (user_configuration_from_key('solr', 'master_path') || path)
110
+ @master_path ||= (user_configuration_from_key('master_solr', 'path') || path)
110
111
  end
111
112
 
112
113
  #
@@ -197,6 +198,13 @@ module Sunspot #:nodoc:
197
198
  end
198
199
  end
199
200
 
201
+ #
202
+ # Solr start jar
203
+ #
204
+ def solr_jar
205
+ @solr_jar ||= user_configuration_from_key('solr', 'solr_jar')
206
+ end
207
+
200
208
  #
201
209
  # Minimum java heap size for Solr instance
202
210
  #
@@ -39,6 +39,11 @@ module Sunspot #:nodoc:
39
39
  # :ignore_attribute_changes_of<Array>::
40
40
  # Define attributes, that should not trigger a reindex of that
41
41
  # object. Usual suspects are updated_at or counters.
42
+ # :include<Mixed>::
43
+ # Define default ActiveRecord includes, set this to allow ActiveRecord
44
+ # to load required associations when indexing. See ActiveRecord's
45
+ # documentation on eager-loading for examples on how to set this
46
+ # Default: []
42
47
  #
43
48
  # ==== Example
44
49
  #
@@ -56,7 +61,9 @@ module Sunspot #:nodoc:
56
61
  def searchable(options = {}, &block)
57
62
  Sunspot.setup(self, &block)
58
63
 
59
- unless searchable?
64
+ if searchable?
65
+ sunspot_options[:include].concat(Util::Array(options[:include]))
66
+ else
60
67
  extend ClassMethods
61
68
  include InstanceMethods
62
69
 
@@ -72,8 +79,10 @@ module Sunspot #:nodoc:
72
79
  searchable.remove_from_index
73
80
  end
74
81
  end
82
+ options[:include] = Util::Array(options[:include])
83
+
84
+ self.sunspot_options = options
75
85
  end
76
- self.sunspot_options = options
77
86
  end
78
87
 
79
88
  #
@@ -127,19 +136,9 @@ module Sunspot #:nodoc:
127
136
  # Sunspot::Search:: Object containing results, totals, facets, etc.
128
137
  #
129
138
  def solr_search(options = {}, &block)
130
- options.assert_valid_keys(:include, :select)
131
- search = Sunspot.new_search(self, &block)
132
- unless options.empty?
133
- search.build do |query|
134
- if options[:include]
135
- query.data_accessor_for(self).include = options[:include]
136
- end
137
- if options[:select]
138
- query.data_accessor_for(self).select = options[:select]
139
- end
140
- end
139
+ solr_execute_search(options) do
140
+ Sunspot.new_search(self, &block)
141
141
  end
142
- search.execute
143
142
  end
144
143
 
145
144
  #
@@ -153,7 +152,9 @@ module Sunspot #:nodoc:
153
152
  # Array:: Array of IDs, in the order returned by the search
154
153
  #
155
154
  def solr_search_ids(&block)
156
- solr_search(&block).raw_results.map { |raw_result| raw_result.primary_key.to_i }
155
+ solr_execute_search_ids do
156
+ solr_search(&block)
157
+ end
157
158
  end
158
159
 
159
160
  #
@@ -222,7 +223,7 @@ module Sunspot #:nodoc:
222
223
  # Post.index(:include => :author)
223
224
  #
224
225
  def solr_index(opts={})
225
- options = { :batch_size => 500, :batch_commit => true, :include => [], :first_id => 0}.merge(opts)
226
+ options = { :batch_size => 500, :batch_commit => true, :include => self.sunspot_options[:include], :first_id => 0}.merge(opts)
226
227
  unless options[:batch_size]
227
228
  Sunspot.index!(all(:include => options[:include]))
228
229
  else
@@ -289,6 +290,27 @@ module Sunspot #:nodoc:
289
290
  true
290
291
  end
291
292
 
293
+ def solr_execute_search(options = {})
294
+ options.assert_valid_keys(:include, :select)
295
+ search = yield
296
+ unless options.empty?
297
+ search.build do |query|
298
+ if options[:include]
299
+ query.data_accessor_for(self).include = options[:include]
300
+ end
301
+ if options[:select]
302
+ query.data_accessor_for(self).select = options[:select]
303
+ end
304
+ end
305
+ end
306
+ search.execute
307
+ end
308
+
309
+ def solr_execute_search_ids(options = {})
310
+ search = yield
311
+ search.raw_results.map { |raw_result| raw_result.primary_key.to_i }
312
+ end
313
+
292
314
  protected
293
315
 
294
316
  #
@@ -301,7 +323,7 @@ module Sunspot #:nodoc:
301
323
  elapsed = Time.now-start
302
324
  logger.info("[#{Time.now}] Completed Indexing. Rows indexed #{counter * batch_size}. Rows/sec: #{batch_size/elapsed.to_f} (Elapsed: #{elapsed} sec.)")
303
325
  end
304
-
326
+
305
327
  end
306
328
 
307
329
  module InstanceMethods
@@ -311,6 +333,8 @@ module Sunspot #:nodoc:
311
333
  alias_method :index!, :solr_index! unless method_defined? :index!
312
334
  alias_method :remove_from_index, :solr_remove_from_index unless method_defined? :remove_from_index
313
335
  alias_method :remove_from_index!, :solr_remove_from_index! unless method_defined? :remove_from_index!
336
+ alias_method :more_like_this, :solr_more_like_this unless method_defined? :more_like_this
337
+ alias_method :more_like_this_ids, :solr_more_like_this_ids unless method_defined? :more_like_this_ids
314
338
  end
315
339
  end
316
340
  #
@@ -351,6 +375,19 @@ module Sunspot #:nodoc:
351
375
  Sunspot.remove!(self)
352
376
  end
353
377
 
378
+ def solr_more_like_this(*args, &block)
379
+ options = args.extract_options!
380
+ self.class.solr_execute_search(options) do
381
+ Sunspot.new_more_like_this(self, *args, &block)
382
+ end
383
+ end
384
+
385
+ def solr_more_like_this_ids(&block)
386
+ self.class.solr_execute_search_ids do
387
+ solr_more_like_this(&block)
388
+ end
389
+ end
390
+
354
391
  private
355
392
 
356
393
  def maybe_mark_for_auto_indexing
@@ -69,6 +69,13 @@ module Sunspot
69
69
  File.join(::Rails.root, 'solr')
70
70
  end
71
71
 
72
+ #
73
+ # Solr start jar
74
+ #
75
+ def solr_jar
76
+ configuration.solr_jar || super
77
+ end
78
+
72
79
  #
73
80
  # Port on which to run Solr
74
81
  #
@@ -24,14 +24,38 @@ namespace :sunspot do
24
24
  task :reindex => :"sunspot:reindex"
25
25
  end
26
26
 
27
- desc 'Reindex all solr models'
28
- task :reindex => :environment do
29
- all_files = Dir.glob(File.join(RAILS_ROOT, 'app', 'models', '*.rb'))
30
- all_models = all_files.map { |path| File.basename(path, '.rb').camelize.constantize }
31
- sunspot_models = all_models.select { |m| m < ActiveRecord::Base and m.searchable? }
32
-
27
+ desc "Reindex all solr models that are located in your application's models directory."
28
+ # This task depends on the standard Rails file naming \
29
+ # conventions, in that the file name matches the defined class name. \
30
+ # By default the indexing system works in batches of 500 records, you can \
31
+ # set your own value for this by using the batch_size argument. You can \
32
+ # also optionally define a list of models to separated by a forward slash '/'
33
+ #
34
+ # $ rake sunspot:reindex # reindex all models
35
+ # $ rake sunspot:reindex[1000] # reindex in batches of 1000
36
+ # $ rake sunspot:reindex[false] # reindex without batching
37
+ # $ rake sunspot:reindex[,Post] # reindex only the Post model
38
+ # $ rake sunspot:reindex[1000,Post] # reindex only the Post model in
39
+ # # batchs of 1000
40
+ # $ rake sunspot:reindex[,Post+Author] # reindex Post and Author model
41
+ task :reindex, :batch_size, :models, :needs => :environment do |t, args|
42
+ reindex_options = {:batch_commit => false}
43
+ case args[:batch_size]
44
+ when 'false'
45
+ reindex_options[:batch_size] = nil
46
+ when /^\d+$/
47
+ reindex_options[:batch_size] = args[:batch_size].to_i if args[:batch_size].to_i > 0
48
+ end
49
+ unless args[:models]
50
+ all_files = Dir.glob(File.join(RAILS_ROOT, 'app', 'models', '*.rb'))
51
+ all_models = all_files.map { |path| File.basename(path, '.rb').camelize.constantize }
52
+ sunspot_models = all_models.select { |m| m < ActiveRecord::Base and m.searchable? }
53
+ else
54
+ sunspot_models = args[:models].split('+').map{|m| m.constantize}
55
+ end
33
56
  sunspot_models.each do |model|
34
- model.solr_reindex :batch_commit => false
57
+ model.solr_reindex reindex_options
35
58
  end
36
59
  end
60
+
37
61
  end
@@ -1,5 +1,5 @@
1
1
  module Sunspot
2
2
  module Rails
3
- VERSION = '1.0.5'
3
+ VERSION = '1.1.0'
4
4
  end
5
5
  end
@@ -1,2 +1,12 @@
1
1
  class Blog < ActiveRecord::Base
2
+ has_many :posts
3
+ has_many :comments, :through => :posts
4
+
5
+ searchable :include => { :posts => :author } do
6
+ string :subdomain
7
+ text :name
8
+ end
9
+
10
+ # Make sure that includes are added to with multiple searchable calls
11
+ searchable(:include => :comments) {}
2
12
  end
@@ -1,8 +1,10 @@
1
1
  class Post < ActiveRecord::Base
2
2
  belongs_to :location
3
+ belongs_to :author
3
4
 
4
5
  searchable :auto_index => false, :auto_remove => false do
5
6
  string :title
7
+ text :body, :more_like_this => true
6
8
  coordinates :location
7
9
  end
8
10
  end
@@ -5,5 +5,6 @@ class PostWithAuto < ActiveRecord::Base
5
5
 
6
6
  searchable :ignore_attribute_changes_of => [ :updated_at ] do
7
7
  string :title
8
+ text :body, :more_like_this => true
8
9
  end
9
10
  end
data/spec/model_spec.rb CHANGED
@@ -195,7 +195,7 @@ describe 'ActiveRecord mixin' do
195
195
 
196
196
  describe 'searchable?()' do
197
197
  it 'should not be true for models that have not been configured for search' do
198
- Blog.should_not be_searchable
198
+ Location.should_not be_searchable
199
199
  end
200
200
 
201
201
  it 'should be true for models that have been configured for search' do
@@ -343,6 +343,15 @@ describe 'ActiveRecord mixin' do
343
343
  end.and_return(@posts)
344
344
  Post.reindex(:include => [{:author => :address}])
345
345
  end
346
+
347
+ it "should set the include option from the searchable options" do
348
+ @blogs = Array.new(10) { Blog.create }
349
+ Blog.should_receive(:all).with do |params|
350
+ params[:include].should == [{ :posts => :author }, :comments]
351
+ @blogs
352
+ end.and_return(@blogs)
353
+ Blog.reindex
354
+ end
346
355
 
347
356
  it "should commit after indexing each batch" do
348
357
  Sunspot.should_receive(:commit).twice
@@ -357,4 +366,44 @@ describe 'ActiveRecord mixin' do
357
366
  end
358
367
  end
359
368
 
369
+ describe "more_like_this()" do
370
+ before(:each) do
371
+ @posts = [
372
+ Post.create!(:title => 'Post123', :body => "one two three"),
373
+ Post.create!(:title => 'Post345', :body => "three four five"),
374
+ Post.create!(:title => 'Post456', :body => "four five six"),
375
+ Post.create!(:title => 'Post234', :body => "two three four"),
376
+ ]
377
+ @posts_with_auto = [
378
+ PostWithAuto.create!(:body => "one two three"),
379
+ PostWithAuto.create!(:body => "four five six")
380
+ ]
381
+ @posts.each { |p| p.index! }
382
+ end
383
+
384
+ it "should return results" do
385
+ @posts.first.more_like_this.results.should == [@posts[3], @posts[1]]
386
+ end
387
+
388
+ it "should return results for specified classes" do
389
+ @posts.first.more_like_this(Post, PostWithAuto).results.to_set.should ==
390
+ Set[@posts_with_auto[0], @posts[1], @posts[3]]
391
+ end
392
+ end
393
+
394
+ describe 'more_like_this_ids()' do
395
+ before :each do
396
+ @posts = [
397
+ Post.create!(:title => 'Post123', :body => "one two three"),
398
+ Post.create!(:title => 'Post345', :body => "three four five"),
399
+ Post.create!(:title => 'Post456', :body => "four five six"),
400
+ Post.create!(:title => 'Post234', :body => "two three four"),
401
+ ]
402
+ @posts.each { |p| p.index! }
403
+ end
404
+
405
+ it 'should return IDs' do
406
+ @posts.first.more_like_this_ids.to_set.should == [@posts[3], @posts[1]].map { |post| post.id }.to_set
407
+ end
408
+ end
360
409
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 1
7
+ - 1
7
8
  - 0
8
- - 5
9
- version: 1.0.5
9
+ version: 1.1.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Mat Brown
@@ -22,7 +22,7 @@ autorequire:
22
22
  bindir: bin
23
23
  cert_chain: []
24
24
 
25
- date: 2010-03-22 00:00:00 -04:00
25
+ date: 2010-04-01 00:00:00 -04:00
26
26
  default_executable:
27
27
  dependencies:
28
28
  - !ruby/object:Gem::Dependency
@@ -34,9 +34,9 @@ dependencies:
34
34
  - !ruby/object:Gem::Version
35
35
  segments:
36
36
  - 1
37
+ - 1
37
38
  - 0
38
- - 5
39
- version: 1.0.5
39
+ version: 1.1.0
40
40
  type: :runtime
41
41
  version_requirements: *id001
42
42
  - !ruby/object:Gem::Dependency