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.
- data/lib/sunspot/rails/configuration.rb +11 -3
- data/lib/sunspot/rails/searchable.rb +54 -17
- data/lib/sunspot/rails/server.rb +7 -0
- data/lib/sunspot/rails/tasks.rb +31 -7
- data/lib/sunspot/rails/version.rb +1 -1
- data/spec/mock_app/app/models/blog.rb +10 -0
- data/spec/mock_app/app/models/post.rb +2 -0
- data/spec/mock_app/app/models/post_with_auto.rb +1 -0
- data/spec/model_spec.rb +50 -1
- metadata +5 -5
@@ -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('
|
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('
|
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('
|
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
|
-
|
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
|
131
|
-
|
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
|
-
|
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
|
data/lib/sunspot/rails/server.rb
CHANGED
data/lib/sunspot/rails/tasks.rb
CHANGED
@@ -24,14 +24,38 @@ namespace :sunspot do
|
|
24
24
|
task :reindex => :"sunspot:reindex"
|
25
25
|
end
|
26
26
|
|
27
|
-
desc
|
28
|
-
task
|
29
|
-
|
30
|
-
|
31
|
-
|
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
|
57
|
+
model.solr_reindex reindex_options
|
35
58
|
end
|
36
59
|
end
|
60
|
+
|
37
61
|
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
|
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
|
-
|
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
|
-
|
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-
|
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
|
-
|
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
|