sunspot 2.5.0 → 2.7.1
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 +14 -3
- data/lib/sunspot/data_extractor.rb +1 -1
- data/lib/sunspot/dsl/fulltext.rb +1 -1
- data/lib/sunspot/dsl/standard_query.rb +29 -1
- data/lib/sunspot/dsl.rb +2 -2
- data/lib/sunspot/field.rb +21 -4
- data/lib/sunspot/indexer.rb +37 -8
- data/lib/sunspot/query/abstract_fulltext.rb +7 -3
- data/lib/sunspot/query/abstract_json_field_facet.rb +3 -0
- data/lib/sunspot/query/composite_fulltext.rb +21 -2
- data/lib/sunspot/query/date_field_json_facet.rb +2 -16
- data/lib/sunspot/query/dismax.rb +10 -4
- data/lib/sunspot/query/function_query.rb +25 -1
- data/lib/sunspot/query/join.rb +1 -1
- data/lib/sunspot/query/range_json_facet.rb +5 -2
- data/lib/sunspot/query/restriction.rb +16 -10
- data/lib/sunspot/query/standard_query.rb +12 -0
- data/lib/sunspot/search/field_json_facet.rb +14 -3
- data/lib/sunspot/session.rb +7 -5
- data/lib/sunspot/setup.rb +38 -0
- data/lib/sunspot/util.rb +24 -21
- data/lib/sunspot/version.rb +1 -1
- data/lib/sunspot.rb +9 -1
- data/spec/api/binding_spec.rb +15 -0
- data/spec/api/indexer/attributes_spec.rb +1 -1
- data/spec/api/indexer/removal_spec.rb +87 -0
- data/spec/api/query/connective_boost_examples.rb +85 -0
- data/spec/api/query/geo_examples.rb +1 -1
- data/spec/api/query/join_spec.rb +2 -2
- data/spec/api/query/standard_spec.rb +10 -0
- data/spec/api/query/types_spec.rb +2 -2
- data/spec/api/session_proxy/master_slave_session_proxy_spec.rb +1 -1
- data/spec/api/session_proxy/retry_5xx_session_proxy_spec.rb +9 -5
- data/spec/api/session_spec.rb +1 -1
- data/spec/api/setup_spec.rb +99 -0
- data/spec/helpers/indexer_helper.rb +22 -0
- data/spec/integration/atomic_updates_spec.rb +169 -5
- data/spec/integration/faceting_spec.rb +68 -34
- data/spec/integration/join_spec.rb +22 -3
- data/spec/integration/scoped_search_spec.rb +78 -0
- data/spec/mocks/comment.rb +1 -1
- data/spec/mocks/connection.rb +6 -0
- data/spec/mocks/photo.rb +11 -7
- data/spec/mocks/post.rb +35 -1
- data/sunspot.gemspec +4 -6
- metadata +33 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f9749564050cadeb45de77d96ed183f7bb07a856b5199fea3bbede0365147e97
|
4
|
+
data.tar.gz: 5bdedfb6911ecbad36de8314822b536c6fb698e6432dcea03bd23be14672dcf7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1850a3b888c9589cb98878344d76d95882ebd95f8aae56095767a0ed3b49787a1c65cb5f1c3c84406afcc2c8cf8da4d533434b9e2850c3bd635a4417d45c14e4
|
7
|
+
data.tar.gz: 5d1a20b95d6f11caab821b186952d05e3c68a86b7e23bf673f451b23fa0429df0f4113e2a91cd12c50617375456b00d41656c7b5c7d402450b08e5df22b69b89
|
data/lib/sunspot/adapters.rb
CHANGED
@@ -55,6 +55,20 @@ module Sunspot
|
|
55
55
|
@instance = instance
|
56
56
|
end
|
57
57
|
|
58
|
+
#
|
59
|
+
# An ID prefix to be added to the index_id
|
60
|
+
#
|
61
|
+
# ==== Returns
|
62
|
+
#
|
63
|
+
# String:: ID prefix for use in index ID to determine
|
64
|
+
# the shard a document is sent to for indexing
|
65
|
+
#
|
66
|
+
def id_prefix
|
67
|
+
setup = Sunspot::Setup.for(@instance.class)
|
68
|
+
|
69
|
+
setup && setup.id_prefix_for(@instance)
|
70
|
+
end
|
71
|
+
|
58
72
|
#
|
59
73
|
# The universally-unique ID for this instance that will be stored in solr
|
60
74
|
#
|
@@ -63,9 +77,6 @@ module Sunspot
|
|
63
77
|
# String:: ID for use in Solr
|
64
78
|
#
|
65
79
|
def index_id #:nodoc:
|
66
|
-
setup = Sunspot::Setup.for(@instance.class)
|
67
|
-
id_prefix = setup ? setup.id_prefix_for(@instance) : nil
|
68
|
-
|
69
80
|
InstanceAdapter.index_id_for("#{id_prefix}#{@instance.class.name}", id)
|
70
81
|
end
|
71
82
|
|
@@ -9,7 +9,7 @@ module Sunspot
|
|
9
9
|
# Abstract extractor to perform common actions on extracted values
|
10
10
|
#
|
11
11
|
class AbstractExtractor
|
12
|
-
BLACKLIST_REGEXP = /[\x0-\x8\xB\xC\xE-\x1F\x7f]/
|
12
|
+
BLACKLIST_REGEXP = /[\x0-\x8\xB\xC\xE-\x1F\x7f\uFFFE-\uFFFF]/
|
13
13
|
|
14
14
|
def value_for(object)
|
15
15
|
extract_value_from(object)
|
data/lib/sunspot/dsl/fulltext.rb
CHANGED
@@ -176,7 +176,7 @@ module Sunspot
|
|
176
176
|
@query.add_additive_boost_function(factor_or_function)
|
177
177
|
else
|
178
178
|
Sunspot::Util.instance_eval_or_call(
|
179
|
-
Scope.new(@query.
|
179
|
+
Scope.new(@query.add_boost_query(factor_or_function), @setup),
|
180
180
|
&block
|
181
181
|
)
|
182
182
|
end
|
@@ -9,7 +9,7 @@ module Sunspot
|
|
9
9
|
# See Sunspot.search for usage examples
|
10
10
|
#
|
11
11
|
class StandardQuery < FieldQuery
|
12
|
-
include Paginatable, Adjustable, Spellcheckable
|
12
|
+
include Paginatable, Adjustable, Spellcheckable, Functional
|
13
13
|
|
14
14
|
# Specify a phrase that should be searched as fulltext. Only +text+
|
15
15
|
# fields are searched - see DSL::Fields.text
|
@@ -123,6 +123,34 @@ module Sunspot
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
#
|
127
|
+
# Defines a boost query
|
128
|
+
#
|
129
|
+
# === Examples
|
130
|
+
#
|
131
|
+
# Sunspot.search(Post) do
|
132
|
+
# with(:blog_id, 1)
|
133
|
+
#
|
134
|
+
# boost(10) do
|
135
|
+
# with(:category_id, 2)
|
136
|
+
# end
|
137
|
+
# end
|
138
|
+
#
|
139
|
+
def boost(factor_or_function, &block)
|
140
|
+
if factor_or_function.is_a?(Sunspot::Query::FunctionQuery)
|
141
|
+
@query.add_boost_function(factor_or_function)
|
142
|
+
else
|
143
|
+
Sunspot::Util.instance_eval_or_call(
|
144
|
+
Scope.new(@query.add_boost_query(factor_or_function), @setup),
|
145
|
+
&block
|
146
|
+
)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def boost_multiplicative(factor_or_function)
|
151
|
+
@query.add_multiplicative_boost_function(factor_or_function)
|
152
|
+
end
|
153
|
+
|
126
154
|
private
|
127
155
|
|
128
156
|
def add_fulltext(keywords, field_names)
|
data/lib/sunspot/dsl.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
%w(spellcheckable fields scope paginatable adjustable field_query
|
2
|
-
standard_query query_facet
|
1
|
+
%w(spellcheckable fields functional scope paginatable adjustable field_query
|
2
|
+
standard_query query_facet fulltext restriction
|
3
3
|
restriction_with_near search more_like_this_query function
|
4
4
|
group field_stats).each do |file|
|
5
5
|
require File.join(File.dirname(__FILE__), 'dsl', file)
|
data/lib/sunspot/field.rb
CHANGED
@@ -195,7 +195,7 @@ module Sunspot
|
|
195
195
|
# Could be of any type
|
196
196
|
#
|
197
197
|
class JoinField < Field #:nodoc:
|
198
|
-
attr_reader :default_boost
|
198
|
+
attr_reader :default_boost
|
199
199
|
|
200
200
|
def initialize(name, type, options = {})
|
201
201
|
@multiple = !!options.delete(:multiple)
|
@@ -213,15 +213,21 @@ module Sunspot
|
|
213
213
|
end
|
214
214
|
|
215
215
|
def from
|
216
|
-
Sunspot::Setup.for(
|
216
|
+
Sunspot::Setup.for(target).field(@join[:from]).indexed_name
|
217
217
|
end
|
218
218
|
|
219
219
|
def to
|
220
220
|
Sunspot::Setup.for(@clazz).field(@join[:to]).indexed_name
|
221
221
|
end
|
222
222
|
|
223
|
-
def local_params
|
224
|
-
|
223
|
+
def local_params(value)
|
224
|
+
query = ["type:\"#{target.name}\""] | Util.Array(value)
|
225
|
+
|
226
|
+
"{!join from=#{from} to=#{to} v='#{query.join(' AND ')}'}"
|
227
|
+
end
|
228
|
+
|
229
|
+
def to_solr_conditional(value)
|
230
|
+
"\"#{value}\""
|
225
231
|
end
|
226
232
|
|
227
233
|
def eql?(field)
|
@@ -229,9 +235,16 @@ module Sunspot
|
|
229
235
|
end
|
230
236
|
|
231
237
|
alias_method :==, :eql?
|
238
|
+
|
239
|
+
def target
|
240
|
+
@target = Util.full_const_get(@target) if @target.is_a?(String)
|
241
|
+
@target
|
242
|
+
end
|
232
243
|
end
|
233
244
|
|
234
245
|
class TypeField #:nodoc:
|
246
|
+
MODULAR_MODEL_MARK = '\:\:'
|
247
|
+
|
235
248
|
class <<self
|
236
249
|
def instance
|
237
250
|
@instance ||= new
|
@@ -245,6 +258,10 @@ module Sunspot
|
|
245
258
|
def to_indexed(clazz)
|
246
259
|
clazz.name
|
247
260
|
end
|
261
|
+
|
262
|
+
def to_solr_conditional(value)
|
263
|
+
value.include?(MODULAR_MODEL_MARK) ? "\"#{value}\"" : value
|
264
|
+
end
|
248
265
|
end
|
249
266
|
|
250
267
|
class IdField #:nodoc:
|
data/lib/sunspot/indexer.rb
CHANGED
@@ -54,9 +54,24 @@ module Sunspot
|
|
54
54
|
# Remove the model from the Solr index by specifying the class and ID
|
55
55
|
#
|
56
56
|
def remove_by_id(class_name, *ids)
|
57
|
+
if class_name.is_a?(String) and class_name.index("!")
|
58
|
+
partition = class_name.rpartition("!")
|
59
|
+
id_prefix = partition[0..1].join
|
60
|
+
class_name = partition[2]
|
61
|
+
else
|
62
|
+
clazz_setup = setup_for_class(Util.full_const_get(class_name))
|
63
|
+
id_prefix = if clazz_setup.id_prefix_defined?
|
64
|
+
if clazz_setup.id_prefix_requires_instance?
|
65
|
+
warn(Sunspot::RemoveByIdNotSupportCompositeIdMessage.call(class_name))
|
66
|
+
else
|
67
|
+
clazz_setup.id_prefix_for_class
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
57
72
|
ids.flatten!
|
58
73
|
@connection.delete_by_id(
|
59
|
-
ids.map { |id| Adapters::InstanceAdapter.index_id_for(class_name, id) }
|
74
|
+
ids.map { |id| Adapters::InstanceAdapter.index_id_for("#{id_prefix}#{class_name}", id) }
|
60
75
|
)
|
61
76
|
end
|
62
77
|
|
@@ -147,13 +162,27 @@ module Sunspot
|
|
147
162
|
)
|
148
163
|
end
|
149
164
|
|
150
|
-
def document_for_atomic_update(clazz,
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
165
|
+
def document_for_atomic_update(clazz, key)
|
166
|
+
return unless Adapters::InstanceAdapter.for(clazz)
|
167
|
+
|
168
|
+
clazz_setup = setup_for_class(clazz)
|
169
|
+
id_prefix = if clazz_setup.id_prefix_defined?
|
170
|
+
if clazz_setup.id_prefix_requires_instance?
|
171
|
+
if key.respond_to?(:id)
|
172
|
+
clazz_setup.id_prefix_for(key)
|
173
|
+
else
|
174
|
+
warn(Sunspot::AtomicUpdateRequireInstanceForCompositeIdMessage.call(clazz.name))
|
175
|
+
end
|
176
|
+
else
|
177
|
+
clazz_setup.id_prefix_for_class
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
instance_id = key.respond_to?(:id) ? key.id : key
|
182
|
+
RSolr::Xml::Document.new(
|
183
|
+
id: Adapters::InstanceAdapter.index_id_for("#{id_prefix}#{clazz.name}", instance_id),
|
184
|
+
type: Util.superclasses_for(clazz).map(&:name)
|
185
|
+
)
|
157
186
|
end
|
158
187
|
#
|
159
188
|
# Get the Setup object for the given object's class.
|
@@ -10,7 +10,7 @@ module Sunspot
|
|
10
10
|
#
|
11
11
|
# Assign a new boost query and return it.
|
12
12
|
#
|
13
|
-
def
|
13
|
+
def add_boost_query(factor)
|
14
14
|
@boost_queries << boost_query = BoostQuery.new(factor)
|
15
15
|
boost_query
|
16
16
|
end
|
@@ -19,14 +19,18 @@ module Sunspot
|
|
19
19
|
# Add a boost function
|
20
20
|
#
|
21
21
|
def add_additive_boost_function(function_query)
|
22
|
-
@additive_boost_functions
|
22
|
+
unless @additive_boost_functions.include?(function_query)
|
23
|
+
@additive_boost_functions << function_query
|
24
|
+
end
|
23
25
|
end
|
24
26
|
|
25
27
|
#
|
26
28
|
# Add a multiplicative boost function
|
27
29
|
#
|
28
30
|
def add_multiplicative_boost_function(function_query)
|
29
|
-
@multiplicative_boost_functions
|
31
|
+
unless @multiplicative_boost_functions.include?(function_query)
|
32
|
+
@multiplicative_boost_functions << function_query
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
#
|
@@ -17,6 +17,9 @@ module Sunspot
|
|
17
17
|
params[:sort] = { @options[:sort] => @options[:sort_type]||'desc' } unless @options[:sort].nil?
|
18
18
|
params[:prefix] = @options[:prefix] unless @options[:prefix].nil?
|
19
19
|
params[:offset] = @options[:offset] unless @options[:offset].nil?
|
20
|
+
params[:allBuckets] = @options[:all_buckets] unless @options[:all_buckets].nil?
|
21
|
+
params[:missing] = @options[:missing] unless @options[:missing].nil?
|
22
|
+
params[:method] = @options[:method] unless @options[:method].nil?
|
20
23
|
|
21
24
|
if !@options[:distinct].nil?
|
22
25
|
dist_opts = @options[:distinct]
|
@@ -3,11 +3,30 @@ module Sunspot
|
|
3
3
|
class CompositeFulltext
|
4
4
|
def initialize
|
5
5
|
@components = []
|
6
|
+
@dismax = nil
|
6
7
|
end
|
7
8
|
|
8
9
|
def add_fulltext(keywords)
|
9
|
-
@components << dismax = Dismax.new(keywords)
|
10
|
-
dismax
|
10
|
+
@components << @dismax = Dismax.new(keywords)
|
11
|
+
@dismax
|
12
|
+
end
|
13
|
+
|
14
|
+
def add_boost_query(factor)
|
15
|
+
@dismax ||= Dismax.new("*:*")
|
16
|
+
@components << @dismax unless @components.include?(@dismax)
|
17
|
+
@dismax.add_boost_query(factor)
|
18
|
+
end
|
19
|
+
|
20
|
+
def add_boost_function(function)
|
21
|
+
@dismax ||= Dismax.new("*:*")
|
22
|
+
@components << @dismax unless @components.include?(@dismax)
|
23
|
+
@dismax.add_additive_boost_function(function)
|
24
|
+
end
|
25
|
+
|
26
|
+
def add_multiplicative_boost_function(function)
|
27
|
+
@dismax ||= Dismax.new("*:*")
|
28
|
+
@components << @dismax unless @components.include?(@dismax)
|
29
|
+
@dismax.add_multiplicative_boost_function(function)
|
11
30
|
end
|
12
31
|
|
13
32
|
def add_join(keywords, target, from, to)
|
@@ -1,24 +1,10 @@
|
|
1
1
|
module Sunspot
|
2
2
|
module Query
|
3
|
-
class DateFieldJsonFacet <
|
3
|
+
class DateFieldJsonFacet < RangeJsonFacet
|
4
4
|
|
5
5
|
def initialize(field, options, setup)
|
6
|
-
raise Exception.new('Need to specify a time_range') if options[:time_range].nil?
|
7
|
-
@start = options[:time_range].first
|
8
|
-
@end = options[:time_range].last
|
9
|
-
@gap = "+#{options[:gap] || 86400}SECONDS"
|
10
6
|
super
|
11
|
-
|
12
|
-
|
13
|
-
def field_name_with_local_params
|
14
|
-
params = {}
|
15
|
-
params[:type] = 'range'
|
16
|
-
params[:field] = @field.indexed_name
|
17
|
-
params[:start] = @field.to_indexed(@start)
|
18
|
-
params[:end] = @field.to_indexed(@end)
|
19
|
-
params[:gap] = @gap
|
20
|
-
params.merge!(init_params)
|
21
|
-
{ @field.name => params }
|
7
|
+
@gap = "+#{@gap}#{options[:gap_unit] || 'SECONDS'}"
|
22
8
|
end
|
23
9
|
end
|
24
10
|
end
|
data/lib/sunspot/query/dismax.rb
CHANGED
@@ -28,10 +28,16 @@ module Sunspot
|
|
28
28
|
# The query as Solr parameters
|
29
29
|
#
|
30
30
|
def to_params
|
31
|
-
params = {
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
params = {
|
32
|
+
:q => @keywords,
|
33
|
+
:defType => 'edismax',
|
34
|
+
:fl => '* score'
|
35
|
+
}
|
36
|
+
|
37
|
+
if @fulltext_fields.any?
|
38
|
+
params[:qf] = @fulltext_fields.values.map { |field| field.to_boosted_field }.join(' ')
|
39
|
+
end
|
40
|
+
|
35
41
|
params[:mm] = @minimum_match if @minimum_match
|
36
42
|
params[:ps] = @phrase_slop if @phrase_slop
|
37
43
|
params[:qs] = @query_phrase_slop if @query_phrase_slop
|
@@ -3,18 +3,25 @@ module Sunspot
|
|
3
3
|
#
|
4
4
|
# Abstract class for function queries.
|
5
5
|
#
|
6
|
-
class FunctionQuery
|
6
|
+
class FunctionQuery
|
7
|
+
attr_reader :boost_amount
|
7
8
|
|
8
9
|
def ^(y)
|
9
10
|
@boost_amount = y
|
10
11
|
self
|
11
12
|
end
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
@boost_amount == other.boost_amount
|
16
|
+
end
|
12
17
|
end
|
13
18
|
|
14
19
|
#
|
15
20
|
# Function query which represents a constant.
|
16
21
|
#
|
17
22
|
class ConstantFunctionQuery < FunctionQuery
|
23
|
+
attr_reader :constant
|
24
|
+
|
18
25
|
def initialize(constant)
|
19
26
|
@constant = constant
|
20
27
|
end
|
@@ -22,12 +29,18 @@ module Sunspot
|
|
22
29
|
def to_s
|
23
30
|
Type.to_literal(@constant) << (@boost_amount ? "^#{@boost_amount}" : "")
|
24
31
|
end
|
32
|
+
|
33
|
+
def ==(other)
|
34
|
+
super and @constant == other.constant
|
35
|
+
end
|
25
36
|
end
|
26
37
|
|
27
38
|
#
|
28
39
|
# Function query which represents a field.
|
29
40
|
#
|
30
41
|
class FieldFunctionQuery < FunctionQuery
|
42
|
+
attr_reader :field
|
43
|
+
|
31
44
|
def initialize(field)
|
32
45
|
@field = field
|
33
46
|
end
|
@@ -35,6 +48,10 @@ module Sunspot
|
|
35
48
|
def to_s
|
36
49
|
"#{Util.escape(@field.indexed_name)}" << (@boost_amount ? "^#{@boost_amount}" : "")
|
37
50
|
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
super and @field == other.field
|
54
|
+
end
|
38
55
|
end
|
39
56
|
|
40
57
|
#
|
@@ -43,6 +60,8 @@ module Sunspot
|
|
43
60
|
# Arguments are in turn FunctionQuery objects.
|
44
61
|
#
|
45
62
|
class FunctionalFunctionQuery < FunctionQuery
|
63
|
+
attr_reader :function_name, :function_args
|
64
|
+
|
46
65
|
def initialize(function_name, function_args)
|
47
66
|
@function_name, @function_args = function_name, function_args
|
48
67
|
end
|
@@ -51,6 +70,11 @@ module Sunspot
|
|
51
70
|
params = @function_args.map { |arg| arg.to_s }.join(",")
|
52
71
|
"#{@function_name}(#{params})" << (@boost_amount ? "^#{@boost_amount}" : "")
|
53
72
|
end
|
73
|
+
|
74
|
+
def ==(other)
|
75
|
+
super and
|
76
|
+
@function_name == other.function_name and @function_args == other.function_args
|
77
|
+
end
|
54
78
|
end
|
55
79
|
end
|
56
80
|
end
|
data/lib/sunspot/query/join.rb
CHANGED
@@ -5,10 +5,12 @@ module Sunspot
|
|
5
5
|
SECONDS_IN_DAY = 86400
|
6
6
|
|
7
7
|
def initialize(field, options, setup)
|
8
|
-
|
8
|
+
options[:range] ||= options[:time_range]
|
9
|
+
raise Exception.new("Need to specify a range") if options[:range].nil? && options[:time_range].nil?
|
9
10
|
@start = options[:range].first
|
10
11
|
@end = options[:range].last
|
11
12
|
@gap = options[:gap] || SECONDS_IN_DAY
|
13
|
+
@other = options[:other]
|
12
14
|
super
|
13
15
|
end
|
14
16
|
|
@@ -19,7 +21,8 @@ module Sunspot
|
|
19
21
|
field: @field.indexed_name,
|
20
22
|
start: @field.to_indexed(@start),
|
21
23
|
end: @field.to_indexed(@end),
|
22
|
-
gap: @gap
|
24
|
+
gap: @gap,
|
25
|
+
other: @other
|
23
26
|
}.merge!(init_params)
|
24
27
|
}
|
25
28
|
end
|
@@ -78,14 +78,14 @@ module Sunspot
|
|
78
78
|
# on whether this restriction is negated.
|
79
79
|
#
|
80
80
|
def to_boolean_phrase
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
81
|
+
value = if negated?
|
82
|
+
to_negated_boolean_phrase
|
83
|
+
else
|
84
|
+
to_positive_boolean_phrase
|
85
|
+
end
|
86
|
+
|
87
|
+
@field.respond_to?(:local_params) ?
|
88
|
+
@field.local_params(value) : value
|
89
89
|
end
|
90
90
|
|
91
91
|
#
|
@@ -208,7 +208,8 @@ module Sunspot
|
|
208
208
|
private
|
209
209
|
|
210
210
|
def to_solr_conditional
|
211
|
-
|
211
|
+
@field.respond_to?(:to_solr_conditional) ?
|
212
|
+
@field.to_solr_conditional(solr_value) : "#{solr_value}"
|
212
213
|
end
|
213
214
|
end
|
214
215
|
|
@@ -316,9 +317,14 @@ module Sunspot
|
|
316
317
|
if @value.empty?
|
317
318
|
"[* TO *]"
|
318
319
|
else
|
319
|
-
"(#{@value.map { |v|
|
320
|
+
"(#{@value.map { |v| to_solr_conditional_per_value v } * ' OR '})"
|
320
321
|
end
|
321
322
|
end
|
323
|
+
|
324
|
+
def to_solr_conditional_per_value(v)
|
325
|
+
@field.respond_to?(:to_solr_conditional) ?
|
326
|
+
@field.to_solr_conditional(solr_value(v)) : "#{solr_value(v)}"
|
327
|
+
end
|
322
328
|
end
|
323
329
|
|
324
330
|
#
|
@@ -16,6 +16,18 @@ module Sunspot
|
|
16
16
|
@fulltext.add_join(keywords, target, from, to)
|
17
17
|
end
|
18
18
|
|
19
|
+
def add_boost_query(factor)
|
20
|
+
@fulltext.add_boost_query(factor)
|
21
|
+
end
|
22
|
+
|
23
|
+
def add_boost_function(function)
|
24
|
+
@fulltext.add_boost_function(function)
|
25
|
+
end
|
26
|
+
|
27
|
+
def add_multiplicative_boost_function(function)
|
28
|
+
@fulltext.add_multiplicative_boost_function(function)
|
29
|
+
end
|
30
|
+
|
19
31
|
def disjunction
|
20
32
|
parent_fulltext = @fulltext
|
21
33
|
@fulltext = @fulltext.add_disjunction
|
@@ -5,15 +5,14 @@ module Sunspot
|
|
5
5
|
attr_reader :name
|
6
6
|
|
7
7
|
def initialize(field, search, options)
|
8
|
-
@name, @search, @options = name, search, options
|
8
|
+
@name, @search, @options = (options[:name] || field.name), search, options
|
9
9
|
@field = field
|
10
10
|
end
|
11
11
|
|
12
12
|
def rows
|
13
13
|
@rows ||=
|
14
14
|
begin
|
15
|
-
|
16
|
-
data = json_facet_response.nil? ? [] : json_facet_response['buckets']
|
15
|
+
data = no_data? ? [] : @search.json_facet_response[@field.name.to_s]['buckets']
|
17
16
|
rows = []
|
18
17
|
data.each do |d|
|
19
18
|
rows << JsonFacetRow.new(d, self)
|
@@ -28,6 +27,18 @@ module Sunspot
|
|
28
27
|
end
|
29
28
|
|
30
29
|
end
|
30
|
+
|
31
|
+
def no_data?
|
32
|
+
@search.json_facet_response[@field.name.to_s].nil?
|
33
|
+
end
|
34
|
+
|
35
|
+
def other_count(type)
|
36
|
+
json_facet_for_field = @search.json_facet_response[@field.name.to_s]
|
37
|
+
return 0 if json_facet_for_field.nil?
|
38
|
+
|
39
|
+
other = json_facet_for_field[type.to_s] || {}
|
40
|
+
other['count']
|
41
|
+
end
|
31
42
|
end
|
32
43
|
end
|
33
44
|
end
|
data/lib/sunspot/session.rb
CHANGED
@@ -256,10 +256,10 @@ module Sunspot
|
|
256
256
|
def connection
|
257
257
|
@connection ||= self.class.connection_class.connect(
|
258
258
|
url: config.solr.url,
|
259
|
-
|
259
|
+
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
|
263
263
|
)
|
264
264
|
end
|
265
265
|
|
@@ -278,9 +278,11 @@ module Sunspot
|
|
278
278
|
end
|
279
279
|
end
|
280
280
|
|
281
|
-
def
|
282
|
-
if config.solr.update_format &&
|
283
|
-
config.solr.update_format.downcase.to_sym
|
281
|
+
def update_format
|
282
|
+
if config.solr.update_format && config.solr.update_format.to_s.match(/xml|json/i)
|
283
|
+
config.solr.update_format.downcase.to_sym
|
284
|
+
else
|
285
|
+
:xml
|
284
286
|
end
|
285
287
|
end
|
286
288
|
end
|
data/lib/sunspot/setup.rb
CHANGED
@@ -302,6 +302,44 @@ module Sunspot
|
|
302
302
|
end
|
303
303
|
end
|
304
304
|
|
305
|
+
#
|
306
|
+
# Get value for `id_prefix` defined as String
|
307
|
+
#
|
308
|
+
# ==== Returns
|
309
|
+
#
|
310
|
+
# String:: value for `id_prefix` defined as String
|
311
|
+
#
|
312
|
+
def id_prefix_for_class
|
313
|
+
return if !id_prefix_defined? || id_prefix_requires_instance?
|
314
|
+
|
315
|
+
@id_prefix_extractor.value_for(nil)
|
316
|
+
end
|
317
|
+
|
318
|
+
#
|
319
|
+
# Check if `id_prefix` is defined for class associated with this setup.
|
320
|
+
#
|
321
|
+
# ==== Returns
|
322
|
+
#
|
323
|
+
# Boolean:: True if class associated with this setup has defined `id_prefix`
|
324
|
+
#
|
325
|
+
def id_prefix_defined?
|
326
|
+
!@id_prefix_extractor.nil?
|
327
|
+
end
|
328
|
+
|
329
|
+
#
|
330
|
+
# Check if instance is required to get `id_prefix` value (instance is required for Proc and
|
331
|
+
# Symbol `id_prefix` only. Value for String `id_prefix` can be get on class level)
|
332
|
+
#
|
333
|
+
# ==== Returns
|
334
|
+
#
|
335
|
+
# Boolean:: True if instance is required to get `id_prefix` value
|
336
|
+
#
|
337
|
+
def id_prefix_requires_instance?
|
338
|
+
return false unless id_prefix_defined?
|
339
|
+
|
340
|
+
!@id_prefix_extractor.is_a?(DataExtractor::Constant)
|
341
|
+
end
|
342
|
+
|
305
343
|
protected
|
306
344
|
|
307
345
|
#
|