stretchy 0.4.0 → 0.4.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/.gitignore +2 -1
- data/.ruby-version +1 -0
- data/lib/stretchy/boosts/base.rb +2 -3
- data/lib/stretchy/boosts/field_decay_boost.rb +23 -19
- data/lib/stretchy/boosts/filter_boost.rb +6 -3
- data/lib/stretchy/boosts/random_boost.rb +7 -4
- data/lib/stretchy/builders/boost_builder.rb +1 -1
- data/lib/stretchy/builders/filter_builder.rb +55 -0
- data/lib/stretchy/builders/match_builder.rb +41 -43
- data/lib/stretchy/builders/query_builder.rb +37 -0
- data/lib/stretchy/builders/shell_builder.rb +53 -0
- data/lib/stretchy/builders/where_builder.rb +88 -159
- data/lib/stretchy/builders.rb +3 -0
- data/lib/stretchy/clauses/base.rb +33 -78
- data/lib/stretchy/clauses/boost_clause.rb +10 -10
- data/lib/stretchy/clauses/boost_match_clause.rb +3 -3
- data/lib/stretchy/clauses/boost_where_clause.rb +5 -5
- data/lib/stretchy/clauses/match_clause.rb +5 -24
- data/lib/stretchy/clauses/where_clause.rb +23 -42
- data/lib/stretchy/errors/validation_error.rb +17 -0
- data/lib/stretchy/errors.rb +1 -1
- data/lib/stretchy/filters/and_filter.rb +5 -1
- data/lib/stretchy/filters/base.rb +2 -2
- data/lib/stretchy/filters/bool_filter.rb +10 -4
- data/lib/stretchy/filters/exists_filter.rb +5 -1
- data/lib/stretchy/filters/geo_filter.rb +13 -7
- data/lib/stretchy/filters/not_filter.rb +5 -2
- data/lib/stretchy/filters/or_filter.rb +4 -1
- data/lib/stretchy/filters/query_filter.rb +5 -1
- data/lib/stretchy/filters/range_filter.rb +10 -5
- data/lib/stretchy/filters/terms_filter.rb +8 -2
- data/lib/stretchy/queries/base.rb +2 -2
- data/lib/stretchy/queries/bool_query.rb +12 -0
- data/lib/stretchy/queries/filtered_query.rb +8 -3
- data/lib/stretchy/queries/function_score_query.rb +25 -32
- data/lib/stretchy/queries/match_query.rb +10 -3
- data/lib/stretchy/results/base.rb +9 -23
- data/lib/stretchy/types/base.rb +2 -2
- data/lib/stretchy/types/geo_point.rb +15 -6
- data/lib/stretchy/types/range.rb +24 -6
- data/lib/stretchy/utils/logger.rb +10 -5
- data/lib/stretchy/utils/validation.rb +77 -0
- data/lib/stretchy/utils.rb +1 -1
- data/lib/stretchy/version.rb +1 -1
- data/lib/stretchy.rb +3 -0
- data/lib/stretchy_validations.rb +10 -0
- data/lib/validation/rule/decay.rb +20 -0
- data/lib/validation/rule/distance.rb +20 -0
- data/lib/validation/rule/field.rb +22 -0
- data/lib/validation/rule/inclusion.rb +33 -0
- data/lib/validation/rule/latitude.rb +21 -0
- data/lib/validation/rule/longitude.rb +22 -0
- data/lib/validation/rule/one_of.rb +22 -0
- data/lib/validation/rule/required.rb +26 -0
- data/lib/validation/rule/responds_to.rb +23 -0
- data/lib/validation/rule/type.rb +41 -0
- data/stretchy.gemspec +2 -0
- metadata +48 -5
- data/lib/stretchy/errors/contract_error.rb +0 -5
- data/lib/stretchy/utils/contract.rb +0 -120
@@ -22,9 +22,9 @@ module Stretchy
|
|
22
22
|
# @return [MatchClause] Temporary clause outside current state
|
23
23
|
def self.tmp(options = {})
|
24
24
|
if options.delete(:inverse)
|
25
|
-
self.new(
|
25
|
+
self.new(Builders::ShellBuilder.new).not(options)
|
26
26
|
else
|
27
|
-
self.new(
|
27
|
+
self.new(Builders::ShellBuilder.new, options)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -52,12 +52,8 @@ module Stretchy
|
|
52
52
|
def initialize(base, opts_or_str = {}, options = {})
|
53
53
|
super(base)
|
54
54
|
if opts_or_str.is_a?(Hash)
|
55
|
-
@inverse = opts_or_str.delete(:inverse) || options.delete(:inverse)
|
56
|
-
@should = opts_or_str.delete(:should) || options.delete(:should)
|
57
55
|
add_params(options.merge(opts_or_str))
|
58
56
|
else
|
59
|
-
@inverse = options.delete(:inverse)
|
60
|
-
@should = options.delete(:should)
|
61
57
|
add_params(options.merge('_all' => opts_or_str))
|
62
58
|
end
|
63
59
|
end
|
@@ -136,9 +132,10 @@ module Stretchy
|
|
136
132
|
# @return [Stretchy::Boosts::FilterBoost] boost containing these match parameters
|
137
133
|
def to_boost(weight = nil)
|
138
134
|
weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT
|
135
|
+
|
139
136
|
Stretchy::Boosts::FilterBoost.new(
|
140
137
|
filter: Stretchy::Filters::QueryFilter.new(
|
141
|
-
|
138
|
+
base.match_builder.to_query
|
142
139
|
),
|
143
140
|
weight: weight
|
144
141
|
)
|
@@ -154,22 +151,6 @@ module Stretchy
|
|
154
151
|
|
155
152
|
private
|
156
153
|
|
157
|
-
def get_storage
|
158
|
-
if inverse?
|
159
|
-
if should?
|
160
|
-
@match_builder.shouldnotmatches
|
161
|
-
else
|
162
|
-
@match_builder.antimatches
|
163
|
-
end
|
164
|
-
else
|
165
|
-
if should?
|
166
|
-
@match_builder.shouldmatches
|
167
|
-
else
|
168
|
-
@match_builder.matches
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end
|
172
|
-
|
173
154
|
def add_params(params = {})
|
174
155
|
case params
|
175
156
|
when Hash
|
@@ -182,7 +163,7 @@ module Stretchy
|
|
182
163
|
end
|
183
164
|
|
184
165
|
def add_param(field, param)
|
185
|
-
|
166
|
+
base.match_builder.add_matches(field, param, inverse: inverse?, should: should?)
|
186
167
|
end
|
187
168
|
|
188
169
|
end
|
@@ -32,9 +32,9 @@ module Stretchy
|
|
32
32
|
# @return [WhereClause] A clause outside the main query context
|
33
33
|
def self.tmp(options = {})
|
34
34
|
if options.delete(:inverse)
|
35
|
-
self.new(
|
35
|
+
self.new(Builders::ShellBuilder.new).not(options)
|
36
36
|
else
|
37
|
-
self.new(
|
37
|
+
self.new(Builders::ShellBuilder.new, options)
|
38
38
|
end
|
39
39
|
end
|
40
40
|
|
@@ -62,7 +62,7 @@ module Stretchy
|
|
62
62
|
#
|
63
63
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html Elastic Docs - Range Filter
|
64
64
|
#
|
65
|
-
def initialize(base, options = {})
|
65
|
+
def initialize(base = nil, options = {})
|
66
66
|
super(base)
|
67
67
|
add_params(options)
|
68
68
|
end
|
@@ -98,7 +98,7 @@ module Stretchy
|
|
98
98
|
# exclusive: true
|
99
99
|
# )
|
100
100
|
def range(field, options = {})
|
101
|
-
|
101
|
+
base.where_builder.add_range(field, options.merge(inverse: inverse?, should: should?))
|
102
102
|
self
|
103
103
|
end
|
104
104
|
|
@@ -124,10 +124,9 @@ module Stretchy
|
|
124
124
|
# lng: 29.2
|
125
125
|
# )
|
126
126
|
def geo(field, options = {})
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
}
|
127
|
+
distance = options[:distance]
|
128
|
+
opts = options.merge(inverse: inverse?, should: should?)
|
129
|
+
base.where_builder.add_geo(field, distance, opts)
|
131
130
|
self
|
132
131
|
end
|
133
132
|
|
@@ -198,54 +197,34 @@ module Stretchy
|
|
198
197
|
def to_boost(weight = nil)
|
199
198
|
weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT
|
200
199
|
|
201
|
-
if
|
200
|
+
if base.match_builder.any? && base.where_builder.any?
|
202
201
|
Stretchy::Boosts::FilterBoost.new(
|
203
202
|
filter: Stretchy::Filters::QueryFilter.new(
|
204
203
|
Stretchy::Queries::FilteredQuery.new(
|
205
|
-
query:
|
206
|
-
filter:
|
204
|
+
query: base.match_builder.to_query,
|
205
|
+
filter: base.where_builder.to_filter
|
207
206
|
)
|
208
207
|
),
|
209
208
|
weight: weight
|
210
209
|
)
|
211
210
|
|
212
|
-
elsif
|
211
|
+
elsif base.match_builder.any?
|
213
212
|
Stretchy::Boosts::FilterBoost.new(
|
214
213
|
filter: Stretchy::Filters::QueryFilter.new(
|
215
|
-
|
214
|
+
base.match_builder.to_query
|
216
215
|
),
|
217
216
|
weight: weight
|
218
217
|
)
|
219
218
|
|
220
|
-
elsif
|
219
|
+
elsif base.where_builder.any?
|
221
220
|
Stretchy::Boosts::FilterBoost.new(
|
222
|
-
filter:
|
221
|
+
filter: base.where_builder.to_filter,
|
223
222
|
weight: weight
|
224
223
|
)
|
225
224
|
end
|
226
225
|
end
|
227
226
|
|
228
227
|
private
|
229
|
-
|
230
|
-
def get_storage(builder_field, is_inverse = nil)
|
231
|
-
is_inverse = inverse? if is_inverse.nil?
|
232
|
-
field = builder_field.to_s
|
233
|
-
if inverse? || is_inverse
|
234
|
-
if should?
|
235
|
-
field = "shouldnot#{field}"
|
236
|
-
else
|
237
|
-
field = "anti#{field}"
|
238
|
-
end
|
239
|
-
else
|
240
|
-
field = "should#{field}" if should?
|
241
|
-
end
|
242
|
-
|
243
|
-
if field =~ /match/
|
244
|
-
@match_builder.send(field)
|
245
|
-
else
|
246
|
-
@where_builder.send(field)
|
247
|
-
end
|
248
|
-
end
|
249
228
|
|
250
229
|
def add_params(options = {})
|
251
230
|
options.each do |field, param|
|
@@ -263,15 +242,17 @@ module Stretchy
|
|
263
242
|
|
264
243
|
def add_param(field, param)
|
265
244
|
case param
|
266
|
-
when nil
|
267
|
-
get_storage(:exists, true) << field
|
268
245
|
when String, Symbol
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
246
|
+
base.match_builder.add_matches(field, param,
|
247
|
+
inverse: inverse?,
|
248
|
+
should: should?,
|
249
|
+
or: true
|
250
|
+
)
|
273
251
|
else
|
274
|
-
|
252
|
+
base.where_builder.add_param(field, param,
|
253
|
+
inverse: inverse?,
|
254
|
+
should: should?
|
255
|
+
)
|
275
256
|
end
|
276
257
|
end
|
277
258
|
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Stretchy
|
2
|
+
module Errors
|
3
|
+
class ValidationError < StandardError
|
4
|
+
|
5
|
+
def initialize(errors)
|
6
|
+
@errors = errors
|
7
|
+
end
|
8
|
+
|
9
|
+
def message
|
10
|
+
@errors.map do |key, err|
|
11
|
+
"Attribute #{key} violated rule #{err[:rule]}"
|
12
|
+
end.join("\n")
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/lib/stretchy/errors.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'stretchy/errors/
|
1
|
+
require 'stretchy/errors/validation_error.rb'
|
@@ -4,7 +4,11 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class AndFilter < Base
|
6
6
|
|
7
|
-
|
7
|
+
attribute :filters
|
8
|
+
validations do
|
9
|
+
rule :filters, :not_empty
|
10
|
+
rule :filters, type: {classes: Filters::Base, array: true}
|
11
|
+
end
|
8
12
|
|
9
13
|
def initialize(*args)
|
10
14
|
@filters = args.flatten
|
@@ -4,16 +4,22 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class BoolFilter < Base
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
|
7
|
+
attribute :must, Array[Base]
|
8
|
+
attribute :must_not, Array[Base]
|
9
|
+
attribute :should, Array[Base]
|
10
|
+
|
11
|
+
validations do
|
12
|
+
rule :must, type: {classes: Base, array: true}
|
13
|
+
rule :must_not, type: {classes: Base, array: true}
|
14
|
+
rule :should, type: {classes: Base, array: true}
|
15
|
+
end
|
10
16
|
|
11
17
|
def initialize(options = {})
|
12
18
|
@must = Array(options[:must])
|
13
19
|
@must_not = Array(options[:must_not])
|
14
20
|
@should = Array(options[:should])
|
21
|
+
require_one!(:must, :must_not, :should)
|
15
22
|
validate!
|
16
|
-
require_one(must: @must, must_not: @must_not, should: @should)
|
17
23
|
end
|
18
24
|
|
19
25
|
def to_search
|
@@ -4,7 +4,11 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class ExistsFilter < Base
|
6
6
|
|
7
|
-
|
7
|
+
attribute :field
|
8
|
+
|
9
|
+
validations do
|
10
|
+
rule :field, :field
|
11
|
+
end
|
8
12
|
|
9
13
|
# CAUTION: this will match empty strings
|
10
14
|
# see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html
|
@@ -5,14 +5,20 @@ module Stretchy
|
|
5
5
|
module Filters
|
6
6
|
class GeoFilter < Base
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
attribute :field
|
9
|
+
attribute :distance
|
10
|
+
attribute :geo_point
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
validations do
|
13
|
+
rule :field, :field
|
14
|
+
rule :geo_point, type: {classes: Types::GeoPoint}
|
15
|
+
rule :distance, :distance
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(field, distance, geo_point)
|
19
|
+
@field = field
|
20
|
+
@distance = distance
|
21
|
+
@geo_point = Types::GeoPoint.new(geo_point)
|
16
22
|
validate!
|
17
23
|
end
|
18
24
|
|
@@ -4,9 +4,12 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class NotFilter < Base
|
6
6
|
|
7
|
-
|
7
|
+
attribute :filters, Array[Base]
|
8
8
|
|
9
|
-
|
9
|
+
validations do
|
10
|
+
rule :filters, type: { classes: Base, array: true }
|
11
|
+
rule :filters, :not_empty
|
12
|
+
end
|
10
13
|
|
11
14
|
def initialize(*filters)
|
12
15
|
@filters = Array(filters).flatten
|
@@ -4,7 +4,10 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class OrFilter < Base
|
6
6
|
|
7
|
-
|
7
|
+
attribute :filters, Array[Base]
|
8
|
+
validations do
|
9
|
+
rule :filters, type: {classes: Base, array: true}
|
10
|
+
end
|
8
11
|
|
9
12
|
def initialize(*args)
|
10
13
|
@filters = args.flatten
|
@@ -5,7 +5,11 @@ module Stretchy
|
|
5
5
|
module Filters
|
6
6
|
class QueryFilter < Base
|
7
7
|
|
8
|
-
|
8
|
+
attribute :query, Queries::Base
|
9
|
+
|
10
|
+
validations do
|
11
|
+
rule :query, type: {classes: Queries::Base}
|
12
|
+
end
|
9
13
|
|
10
14
|
def initialize(query)
|
11
15
|
@query = query
|
@@ -5,12 +5,17 @@ module Stretchy
|
|
5
5
|
module Filters
|
6
6
|
class RangeFilter < Base
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
attribute :field
|
9
|
+
attribute :range, Types::Range
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
11
|
+
validations do
|
12
|
+
rule :field, :field
|
13
|
+
rule :range, type: {classes: Types::Range}
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(field, range_options)
|
17
|
+
@field = field
|
18
|
+
@range = Types::Range.new(range_options)
|
14
19
|
validate!
|
15
20
|
end
|
16
21
|
|
@@ -4,8 +4,14 @@ module Stretchy
|
|
4
4
|
module Filters
|
5
5
|
class TermsFilter < Base
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
attribute :field
|
8
|
+
attribute :terms
|
9
|
+
|
10
|
+
validations do
|
11
|
+
rule :field, :field
|
12
|
+
rule :terms, type: {classes: [Numeric, Time, String, Symbol], array: true}
|
13
|
+
rule :terms, :not_empty
|
14
|
+
end
|
9
15
|
|
10
16
|
def initialize(field, terms)
|
11
17
|
@field = field
|
@@ -4,10 +4,22 @@ module Stretchy
|
|
4
4
|
module Queries
|
5
5
|
class BoolQuery < Base
|
6
6
|
|
7
|
+
attribute :must, Array
|
8
|
+
attribute :must_not, Array
|
9
|
+
attribute :should, Array
|
10
|
+
|
11
|
+
validations do
|
12
|
+
rule :must, type: {classes: Base, array: true}
|
13
|
+
rule :must_not, type: {classes: Base, array: true}
|
14
|
+
rule :should, type: {classes: Base, array: true}
|
15
|
+
end
|
16
|
+
|
7
17
|
def initialize(options = {})
|
8
18
|
@must = Array(options[:must])
|
9
19
|
@must_not = Array(options[:must_not])
|
10
20
|
@should = Array(options[:should])
|
21
|
+
require_one! :must, :must_not, :should
|
22
|
+
validate!
|
11
23
|
end
|
12
24
|
|
13
25
|
def to_search
|
@@ -5,14 +5,19 @@ module Stretchy
|
|
5
5
|
module Queries
|
6
6
|
class FilteredQuery < Base
|
7
7
|
|
8
|
-
|
9
|
-
|
8
|
+
attribute :query, Base
|
9
|
+
attribute :filter, Filters::Base
|
10
|
+
|
11
|
+
validations do
|
12
|
+
rule :query, type: {classes: Base}
|
13
|
+
rule :filter, type: {classes: Filters::Base}
|
14
|
+
end
|
10
15
|
|
11
16
|
def initialize(options = {})
|
12
17
|
@query = options[:query]
|
13
18
|
@filter = options[:filter]
|
19
|
+
require_one! :query, :filter
|
14
20
|
validate!
|
15
|
-
require_one(query: @query, filter: @filter)
|
16
21
|
end
|
17
22
|
|
18
23
|
def to_search
|
@@ -8,39 +8,38 @@ module Stretchy
|
|
8
8
|
SCORE_MODES = %w(multiply sum avg first max min)
|
9
9
|
BOOST_MODES = %w(multiply replace sum avg max min)
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
11
|
+
attribute :functions, Array[Boosts::Base]
|
12
|
+
attribute :query, Base
|
13
|
+
attribute :filter, Filters::Base
|
14
|
+
attribute :score_mode
|
15
|
+
attribute :boost_mode
|
16
|
+
attribute :min_score
|
17
|
+
attribute :max_boost
|
18
|
+
attribute :boost
|
19
|
+
|
20
|
+
validations do
|
21
|
+
rule :functions, type: {classes: Boosts::Base, array: true}
|
22
|
+
rule :query, type: {classes: Base}
|
23
|
+
rule :filter, type: {classes: Filters::Base}
|
24
|
+
rule :score_mode, inclusion: {in: SCORE_MODES}
|
25
|
+
rule :boost_mode, inclusion: {in: BOOST_MODES}
|
26
|
+
rule :min_score, type: {classes: Numeric}
|
27
|
+
rule :max_boost, type: {classes: Numeric}
|
28
|
+
rule :boost, type: {classes: Numeric}
|
29
|
+
end
|
19
30
|
|
20
31
|
def initialize(options = {})
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
self.class.attributes.map do |field|
|
26
|
-
instance_variable_set("@#{field}", options[field])
|
27
|
-
end
|
32
|
+
self.class.attribute_set.set(self, options) if options
|
33
|
+
set_default_attributes
|
34
|
+
require_only_one! :query, :filter
|
28
35
|
validate!
|
29
|
-
validate_query_or_filter
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.attributes
|
33
|
-
[:boost, :max_boost, :score_mode, :boost_mode, :min_score]
|
34
|
-
end
|
35
|
-
|
36
|
-
def validate_query_or_filter
|
37
|
-
if @query && @filter
|
38
|
-
raise Stretchy::Errors::ContractError.new "Cannot have both query and filter -- combine using a FilteredQuery"
|
39
|
-
end
|
40
36
|
end
|
41
37
|
|
42
38
|
def to_search
|
43
39
|
json = {}
|
40
|
+
attributes.each do |field, value|
|
41
|
+
json[field] = value if value
|
42
|
+
end
|
44
43
|
json[:functions] = @functions.map(&:to_search)
|
45
44
|
if @query
|
46
45
|
json[:query] = @query.to_search
|
@@ -50,12 +49,6 @@ module Stretchy
|
|
50
49
|
json[:query] = Stretchy::Queries::MatchAllQuery.new.to_search
|
51
50
|
end
|
52
51
|
|
53
|
-
self.class.attributes.reduce(json) do |body, field|
|
54
|
-
ivar = instance_variable_get("@#{field}")
|
55
|
-
body[field] = ivar if ivar
|
56
|
-
body
|
57
|
-
end
|
58
|
-
|
59
52
|
{ function_score: json }
|
60
53
|
end
|
61
54
|
end
|
@@ -6,9 +6,16 @@ module Stretchy
|
|
6
6
|
|
7
7
|
OPERATORS = ['and', 'or']
|
8
8
|
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
attribute :field
|
10
|
+
attribute :string
|
11
|
+
attribute :operator
|
12
|
+
|
13
|
+
validations do
|
14
|
+
rule :field, :field
|
15
|
+
rule :operator, inclusion: {in: OPERATORS}
|
16
|
+
rule :string, type: {classes: String}
|
17
|
+
rule :string, :required
|
18
|
+
end
|
12
19
|
|
13
20
|
def initialize(options = {})
|
14
21
|
case options
|
@@ -4,41 +4,27 @@ module Stretchy
|
|
4
4
|
|
5
5
|
extend Forwardable
|
6
6
|
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :base, :index_name
|
8
8
|
|
9
|
-
delegate [:type, :current_page, :
|
9
|
+
delegate [:type, :current_page, :fields, :offset, :limit,
|
10
|
+
:aggregations] => :base
|
10
11
|
|
11
|
-
def initialize(
|
12
|
-
@
|
13
|
-
@index_name =
|
12
|
+
def initialize(base)
|
13
|
+
@base = base
|
14
|
+
@index_name = base.index || Stretchy.index_name
|
14
15
|
end
|
15
16
|
|
16
|
-
def limit
|
17
|
-
clause.get_limit
|
18
|
-
end
|
19
17
|
alias :per_page :limit
|
20
18
|
alias :limit_value :limit
|
21
19
|
|
22
|
-
def fields
|
23
|
-
clause.get_fields
|
24
|
-
end
|
25
|
-
|
26
|
-
def offset
|
27
|
-
clause.get_offset
|
28
|
-
end
|
29
|
-
|
30
|
-
def page
|
31
|
-
clause.get_page
|
32
|
-
end
|
33
|
-
|
34
20
|
def total_pages
|
35
21
|
[(total.to_f / limit).ceil, 1].max
|
36
22
|
end
|
37
23
|
|
38
24
|
def request
|
39
25
|
return @request if @request
|
40
|
-
@request = {query:
|
41
|
-
@request[:aggs] =
|
26
|
+
@request = {query: base.to_search}
|
27
|
+
@request[:aggs] = base.aggregate_builder if base.aggregate_builder.any?
|
42
28
|
@request
|
43
29
|
end
|
44
30
|
|
@@ -50,7 +36,7 @@ module Stretchy
|
|
50
36
|
size: limit
|
51
37
|
}
|
52
38
|
params[:fields] = fields if fields
|
53
|
-
params[:explain] = true if
|
39
|
+
params[:explain] = true if base.explain
|
54
40
|
@response ||= Stretchy.search(params)
|
55
41
|
end
|
56
42
|
|
data/lib/stretchy/types/base.rb
CHANGED
@@ -4,16 +4,25 @@ module Stretchy
|
|
4
4
|
module Types
|
5
5
|
class GeoPoint < Base
|
6
6
|
|
7
|
-
|
7
|
+
attribute :lat
|
8
|
+
attribute :lon
|
8
9
|
|
9
|
-
|
10
|
-
|
10
|
+
validations do
|
11
|
+
rule :lat, :latitude
|
12
|
+
rule :lon, :longitude
|
13
|
+
end
|
11
14
|
|
15
|
+
attr_reader :lat, :lon
|
12
16
|
|
13
17
|
def initialize(options = {})
|
14
|
-
|
15
|
-
|
16
|
-
|
18
|
+
if options.is_a?(self.class)
|
19
|
+
@lat = options.lat
|
20
|
+
@lon = options.lon
|
21
|
+
else
|
22
|
+
@lat = options[:lat] || options[:latitude]
|
23
|
+
@lon = options[:lng] || options[:lon] ||
|
24
|
+
options[:longitude]
|
25
|
+
end
|
17
26
|
|
18
27
|
validate!
|
19
28
|
end
|