sunspot_rails 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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