sunspot 2.4.0 → 2.5.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.
- 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
|