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.
- 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
|