sunspot 2.4.0 → 2.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/sunspot/adapters.rb +4 -1
- data/lib/sunspot/dsl/fields.rb +16 -0
- data/lib/sunspot/search/hit.rb +6 -1
- data/lib/sunspot/session.rb +7 -1
- data/lib/sunspot/setup.rb +31 -0
- data/lib/sunspot/version.rb +1 -1
- data/spec/api/adapters_spec.rb +13 -0
- data/spec/api/search/hits_spec.rb +14 -0
- data/spec/api/sunspot_spec.rb +3 -0
- data/spec/integration/field_lists_spec.rb +16 -0
- data/spec/mocks/adapters.rb +33 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 179de5f5261bdb69d21038a0b2e36fbd2812e1fc71ef4c1efd77979a03e58179
|
4
|
+
data.tar.gz: 1f7f40d9737400cf61c23515c61ebde70140b1c1bf9df800d7e19ce27c3cbd0d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ad59d5868f3461648d29c77b6368d7c5145ef6247ecca38878bf4f03bb3d2ab73fea2decf629936d58282b8067345198f6bff82be1347bb0cc92cb4537722d28
|
7
|
+
data.tar.gz: 3c4fd67940331fbdacffd665ca624119038bf12da2aa2b041adbd8260aef3921660b83803a912cf81384c7269f6b46d3b7fad1c883c34e1a1ba2ccbade2fd6dc
|
data/lib/sunspot/adapters.rb
CHANGED
@@ -63,7 +63,10 @@ module Sunspot
|
|
63
63
|
# String:: ID for use in Solr
|
64
64
|
#
|
65
65
|
def index_id #:nodoc:
|
66
|
-
|
66
|
+
setup = Sunspot::Setup.for(@instance.class)
|
67
|
+
id_prefix = setup ? setup.id_prefix_for(@instance) : nil
|
68
|
+
|
69
|
+
InstanceAdapter.index_id_for("#{id_prefix}#{@instance.class.name}", id)
|
67
70
|
end
|
68
71
|
|
69
72
|
class <<self
|
data/lib/sunspot/dsl/fields.rb
CHANGED
@@ -55,6 +55,22 @@ module Sunspot
|
|
55
55
|
@setup.add_document_boost(attr_name, &block)
|
56
56
|
end
|
57
57
|
|
58
|
+
#
|
59
|
+
# If you use the compositeId router for shards, you can send documents
|
60
|
+
# with a prefix in the document ID which will be used to calculate the
|
61
|
+
# hash Solr uses to determine the shard a document is sent to for indexing.
|
62
|
+
# The prefix can be anything you’d like it to be (it doesn’t have to be
|
63
|
+
# the shard name, for example), but it must be consistent so Solr
|
64
|
+
# behaves consistently.
|
65
|
+
#
|
66
|
+
# ==== Parameters
|
67
|
+
#
|
68
|
+
# attr_name<Symbol,String>:: Attribute name to call or a string constant
|
69
|
+
#
|
70
|
+
def id_prefix(attr_name = nil, &block)
|
71
|
+
@setup.add_id_prefix(attr_name, &block)
|
72
|
+
end
|
73
|
+
|
58
74
|
# method_missing is used to provide access to typed fields, because
|
59
75
|
# developers should be able to add new Sunspot::Type implementations
|
60
76
|
# dynamically and have them recognized inside the Fields DSL. Like #text,
|
data/lib/sunspot/search/hit.rb
CHANGED
@@ -17,6 +17,10 @@ module Sunspot
|
|
17
17
|
# Class name of object associated with this hit, as string.
|
18
18
|
#
|
19
19
|
attr_reader :class_name
|
20
|
+
#
|
21
|
+
# ID prefix used for compositeId shard router
|
22
|
+
#
|
23
|
+
attr_reader :id_prefix
|
20
24
|
#
|
21
25
|
# Keyword relevance score associated with this result. Nil if this hit
|
22
26
|
# is not from a keyword search.
|
@@ -27,7 +31,8 @@ module Sunspot
|
|
27
31
|
attr_writer :result #:nodoc:
|
28
32
|
|
29
33
|
def initialize(raw_hit, highlights, search) #:nodoc:
|
30
|
-
@class_name, @primary_key =
|
34
|
+
@id_prefix, @class_name, @primary_key =
|
35
|
+
*raw_hit['id'].match(/((?:[^!]+!)+)*([^\s]+)\s(.+)/)[1..3]
|
31
36
|
@score = raw_hit['score']
|
32
37
|
@search = search
|
33
38
|
@stored_values = raw_hit
|
data/lib/sunspot/session.rb
CHANGED
@@ -259,7 +259,7 @@ module Sunspot
|
|
259
259
|
read_timeout: config.solr.read_timeout,
|
260
260
|
open_timeout: config.solr.open_timeout,
|
261
261
|
proxy: config.solr.proxy,
|
262
|
-
update_format:
|
262
|
+
update_format: update_format_generator
|
263
263
|
)
|
264
264
|
end
|
265
265
|
|
@@ -277,5 +277,11 @@ module Sunspot
|
|
277
277
|
CompositeSetup.for(types)
|
278
278
|
end
|
279
279
|
end
|
280
|
+
|
281
|
+
def update_format_generator
|
282
|
+
if config.solr.update_format && RSolr.version.to_i > 1
|
283
|
+
config.solr.update_format.downcase.to_sym == :json ? RSolr::JSON::Generator : RSolr::Xml::Generator
|
284
|
+
end
|
285
|
+
end
|
280
286
|
end
|
281
287
|
end
|
data/lib/sunspot/setup.rb
CHANGED
@@ -15,6 +15,7 @@ module Sunspot
|
|
15
15
|
@more_like_this_field_factories_cache = Hash.new { |h, k| h[k] = [] }
|
16
16
|
@dsl = DSL::Fields.new(self)
|
17
17
|
@document_boost_extractor = nil
|
18
|
+
@id_prefix_extractor = nil
|
18
19
|
add_field_factory(:class, Type::ClassType.instance)
|
19
20
|
end
|
20
21
|
|
@@ -61,6 +62,7 @@ module Sunspot
|
|
61
62
|
field_factory = FieldFactory::Static.new(name, Type::TextType.instance, options, &block)
|
62
63
|
@text_field_factories[name] = field_factory
|
63
64
|
@text_field_factories_cache[field_factory.name] = field_factory
|
65
|
+
@field_factories_cache[field_factory.name] = field_factory
|
64
66
|
if stored
|
65
67
|
@stored_field_factories_cache[field_factory.name] << field_factory
|
66
68
|
end
|
@@ -81,6 +83,7 @@ module Sunspot
|
|
81
83
|
field_factory = FieldFactory::Dynamic.new(name, type, options, &block)
|
82
84
|
@dynamic_field_factories[field_factory.signature] = field_factory
|
83
85
|
@dynamic_field_factories_cache[field_factory.name] = field_factory
|
86
|
+
@field_factories_cache[field_factory.name] = field_factory
|
84
87
|
if stored
|
85
88
|
@stored_field_factories_cache[field_factory.name] << field_factory
|
86
89
|
end
|
@@ -107,6 +110,24 @@ module Sunspot
|
|
107
110
|
end
|
108
111
|
end
|
109
112
|
|
113
|
+
#
|
114
|
+
# Add id prefix for compositeId router
|
115
|
+
#
|
116
|
+
def add_id_prefix(attr_name, &block)
|
117
|
+
@id_prefix_extractor =
|
118
|
+
case attr_name
|
119
|
+
when Symbol
|
120
|
+
DataExtractor::AttributeExtractor.new(attr_name)
|
121
|
+
when String
|
122
|
+
DataExtractor::Constant.new(attr_name)
|
123
|
+
when nil
|
124
|
+
DataExtractor::BlockExtractor.new(&block) if block_given?
|
125
|
+
else
|
126
|
+
raise ArgumentError,
|
127
|
+
"The ID prefix has to be either a Symbol, a String or a Proc"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
110
131
|
#
|
111
132
|
# Builder method for evaluating the setup DSL
|
112
133
|
#
|
@@ -271,6 +292,16 @@ module Sunspot
|
|
271
292
|
end
|
272
293
|
end
|
273
294
|
|
295
|
+
def id_prefix_for(model)
|
296
|
+
if @id_prefix_extractor
|
297
|
+
value = @id_prefix_extractor.value_for(model)
|
298
|
+
|
299
|
+
if value.is_a?(String) and value.size > 0
|
300
|
+
value[-1] == "!" ? value : "#{value}!"
|
301
|
+
end
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
274
305
|
protected
|
275
306
|
|
276
307
|
#
|
data/lib/sunspot/version.rb
CHANGED
data/spec/api/adapters_spec.rb
CHANGED
@@ -20,6 +20,19 @@ describe Sunspot::Adapters::InstanceAdapter do
|
|
20
20
|
Sunspot::Adapters::InstanceAdapter::for(UnseenModel)
|
21
21
|
expect(Sunspot::Adapters::InstanceAdapter::registered_adapter_for(UnseenModel)).to be(AbstractModelInstanceAdapter)
|
22
22
|
end
|
23
|
+
|
24
|
+
it "appends ID prefix when configured" do
|
25
|
+
expect(AbstractModelInstanceAdapter.new(ModelWithPrefixId.new).index_id).to eq "USERDATA!ModelWithPrefixId 1"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "supports nested ID prefixes" do
|
29
|
+
expect(AbstractModelInstanceAdapter.
|
30
|
+
new(ModelWithNestedPrefixId.new).index_id).to eq "USER!USERDATA!ModelWithNestedPrefixId 1"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "doesn't appends ID prefix when not configured" do
|
34
|
+
expect(AbstractModelInstanceAdapter.new(ModelWithoutPrefixId.new).index_id).to eq "ModelWithoutPrefixId 1"
|
35
|
+
end
|
23
36
|
end
|
24
37
|
|
25
38
|
describe Sunspot::Adapters::DataAccessor do
|
@@ -12,6 +12,20 @@ describe 'hits', :type => :search do
|
|
12
12
|
end).to eq([['Post', post_1.id.to_s], ['Post', post_2.id.to_s]])
|
13
13
|
end
|
14
14
|
|
15
|
+
it "should return ID prefix when used with compositeId shard router" do
|
16
|
+
Sunspot.index!(ModelWithPrefixId.new)
|
17
|
+
|
18
|
+
expect(Sunspot.search(ModelWithPrefixId).
|
19
|
+
hits.map { |h| h.id_prefix }.uniq).to eq ["USERDATA!"]
|
20
|
+
end
|
21
|
+
|
22
|
+
it "should parse nested ID prefixes" do
|
23
|
+
Sunspot.index!(ModelWithNestedPrefixId.new)
|
24
|
+
|
25
|
+
expect(Sunspot.search(ModelWithNestedPrefixId).
|
26
|
+
hits.map { |h| h.id_prefix }.uniq).to eq ["USER!USERDATA!"]
|
27
|
+
end
|
28
|
+
|
15
29
|
it 'returns search total as attribute of hits' do
|
16
30
|
stub_results(Post.new, 4)
|
17
31
|
expect(session.search(Post) do
|
data/spec/api/sunspot_spec.rb
CHANGED
@@ -31,6 +31,22 @@ describe 'fields lists' do
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
+
it 'does not raise Sunspot::UnrecognizedFieldError when listing existing text fields' do
|
35
|
+
expect do
|
36
|
+
Sunspot.search(Post) {
|
37
|
+
field_list(:body)
|
38
|
+
}
|
39
|
+
end.to_not raise_error
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'does raise Sunspot::UnrecognizedFieldError when listing a non-existent text fields' do
|
43
|
+
expect do
|
44
|
+
Sunspot.search(Post) {
|
45
|
+
field_list(:bogus_body)
|
46
|
+
}
|
47
|
+
end.to raise_error(Sunspot::UnrecognizedFieldError)
|
48
|
+
end
|
49
|
+
|
34
50
|
it 'does not load any stored fields' do
|
35
51
|
hit = Sunspot.search(Post) { without_stored_fields }.hits.first
|
36
52
|
|
data/spec/mocks/adapters.rb
CHANGED
@@ -7,7 +7,40 @@ end
|
|
7
7
|
class UnseenModel < AbstractModel
|
8
8
|
end
|
9
9
|
|
10
|
+
class ModelWithPrefixId < AbstractModel
|
11
|
+
def id
|
12
|
+
1
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Sunspot.setup(ModelWithPrefixId) do
|
17
|
+
id_prefix { "USERDATA!" }
|
18
|
+
end
|
19
|
+
|
20
|
+
class ModelWithNestedPrefixId < AbstractModel
|
21
|
+
def id
|
22
|
+
1
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
Sunspot.setup(ModelWithNestedPrefixId) do
|
27
|
+
id_prefix { "USER!USERDATA!" }
|
28
|
+
end
|
29
|
+
|
30
|
+
class ModelWithoutPrefixId < AbstractModel
|
31
|
+
def id
|
32
|
+
1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
Sunspot.setup(ModelWithoutPrefixId) do
|
37
|
+
end
|
38
|
+
|
39
|
+
|
10
40
|
class AbstractModelInstanceAdapter < Sunspot::Adapters::InstanceAdapter
|
41
|
+
def id
|
42
|
+
@instance.id
|
43
|
+
end
|
11
44
|
end
|
12
45
|
|
13
46
|
class AbstractModelDataAccessor < Sunspot::Adapters::DataAccessor
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sunspot
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mat Brown
|
@@ -30,7 +30,7 @@ authors:
|
|
30
30
|
autorequire:
|
31
31
|
bindir: bin
|
32
32
|
cert_chain: []
|
33
|
-
date: 2019-07-
|
33
|
+
date: 2019-07-12 00:00:00.000000000 Z
|
34
34
|
dependencies:
|
35
35
|
- !ruby/object:Gem::Dependency
|
36
36
|
name: rsolr
|