stretchy 0.4.6 → 0.4.7
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/.editorconfig +12 -0
- data/CONTRIBUTING.md +52 -0
- data/README.md +157 -40
- data/lib/stretchy/builders/filter_builder.rb +12 -7
- data/lib/stretchy/builders/query_builder.rb +1 -1
- data/lib/stretchy/builders/where_builder.rb +7 -3
- data/lib/stretchy/clauses/base.rb +63 -57
- data/lib/stretchy/clauses/boost_clause.rb +47 -49
- data/lib/stretchy/clauses/boost_match_clause.rb +52 -19
- data/lib/stretchy/clauses/boost_where_clause.rb +46 -28
- data/lib/stretchy/clauses/match_clause.rb +52 -42
- data/lib/stretchy/clauses/where_clause.rb +86 -70
- data/lib/stretchy/filters/params_filter.rb +27 -0
- data/lib/stretchy/filters.rb +1 -0
- data/lib/stretchy/queries/params_query.rb +21 -0
- data/lib/stretchy/queries.rb +1 -0
- data/lib/stretchy/version.rb +1 -1
- metadata +6 -2
@@ -2,37 +2,34 @@ require 'stretchy/clauses/base'
|
|
2
2
|
|
3
3
|
module Stretchy
|
4
4
|
module Clauses
|
5
|
-
#
|
6
|
-
# A Where clause inherits the same state as any clause,
|
5
|
+
#
|
6
|
+
# A Where clause inherits the same state as any clause,
|
7
7
|
# but has a few possible states to transition to. You
|
8
8
|
# can call {#range} and {#geo} to add their respective
|
9
9
|
# filters, or you can transition to the inverted state
|
10
10
|
# via {#not}, or the `should` state via {#should}
|
11
|
-
#
|
11
|
+
#
|
12
12
|
# ### STATES:
|
13
13
|
# * **inverted:** any filters added in this state will be
|
14
14
|
# inverted, ie the document must **NOT** match said
|
15
15
|
# filters.
|
16
16
|
# * **should:** any filters added in this state will be
|
17
17
|
# applied to a `should` block. Documents which do
|
18
|
-
# not match these filters will be returned, but
|
19
|
-
# documents which do match will have a higher
|
18
|
+
# not match these filters will be returned, but
|
19
|
+
# documents which do match will have a higher
|
20
20
|
# relevance score.
|
21
|
-
#
|
21
|
+
#
|
22
22
|
# @author [atevans]
|
23
|
-
#
|
23
|
+
#
|
24
24
|
class WhereClause < Base
|
25
25
|
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
# @param base [Base] Used to intialize the new state from the previous clause
|
26
|
+
#
|
27
|
+
# Add term-style filters to the query. This is similar to ActiveRecord's `where`
|
28
|
+
# method. Also exits any should or inverse state. To add terms to those states,
|
29
|
+
# chain the `.should` or `.not` methods after this one.
|
30
|
+
#
|
32
31
|
# @param params = {} [Hash] filters to be applied to the new state
|
33
|
-
#
|
34
|
-
# @option params [true, false] :should (nil) Whether the new state is should
|
35
|
-
#
|
32
|
+
#
|
36
33
|
# @example Apply ActiveRecord-like filters
|
37
34
|
# query.where(
|
38
35
|
# string_field: "string",
|
@@ -40,13 +37,18 @@ module Stretchy
|
|
40
37
|
# in_range: 27..33,
|
41
38
|
# included_in: [47, 23, 86]
|
42
39
|
# )
|
43
|
-
#
|
40
|
+
#
|
41
|
+
# @example Apply should filters
|
42
|
+
# query.where.should(
|
43
|
+
# string_field: "string"
|
44
|
+
# )
|
45
|
+
#
|
44
46
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html Elastic Docs - Terms Filter
|
45
|
-
#
|
47
|
+
#
|
46
48
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-exists-filter.html Elastic Docs - Exists Filter
|
47
|
-
#
|
49
|
+
#
|
48
50
|
# @see http://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-range-filter.html Elastic Docs - Range Filter
|
49
|
-
#
|
51
|
+
#
|
50
52
|
def where(params = {}, options = {})
|
51
53
|
@inverse = false
|
52
54
|
@should = false
|
@@ -54,58 +56,73 @@ module Stretchy
|
|
54
56
|
self
|
55
57
|
end
|
56
58
|
|
57
|
-
#
|
59
|
+
#
|
60
|
+
# Add arbitrary json as a filter in the appropriate context.
|
61
|
+
# This can be used to add filters that are not currently supported
|
62
|
+
# by Stretchy to be used in the final query.
|
63
|
+
#
|
64
|
+
# @param params = {} [Hash] Filter to be applied to the new state
|
65
|
+
# @option options [true, false] :inverse (nil) Ignore query state and add to the `not` filters
|
66
|
+
# @option options [true, false] :should (nil) Ignore query state and add to the `should` filters
|
67
|
+
def filter(params, options = {})
|
68
|
+
base.where_builder.add_filter(
|
69
|
+
Filters::ParamsFilter.new(params),
|
70
|
+
merge_state(options)
|
71
|
+
)
|
72
|
+
self
|
73
|
+
end
|
74
|
+
|
75
|
+
#
|
58
76
|
# Accessor for `@should`
|
59
|
-
#
|
77
|
+
#
|
60
78
|
# @return [true, false] `@should`
|
61
79
|
def should?
|
62
80
|
!!@should
|
63
81
|
end
|
64
82
|
|
65
|
-
#
|
83
|
+
#
|
66
84
|
# Add a range filter to the current context. While
|
67
85
|
# you can pass a `Range` object to {#where}, this
|
68
86
|
# allows you to specify an open-ended range, such
|
69
87
|
# as only specifying the minimum or maximum value.
|
70
|
-
#
|
88
|
+
#
|
71
89
|
# @param field [String, Symbol] The field to filter with this range
|
72
90
|
# @param options = {} [Hash] Options for the range
|
73
91
|
# @option options [Numeric] :min (nil) Minimum. Ranges are _inclusive_ by default
|
74
92
|
# @option options [Numeric] :max (nil) Maximum. Ranges are _inclusive_ by default
|
75
|
-
# @option options [true, false] :exclusive (nil) Overrides default and makes the range exclusive -
|
93
|
+
# @option options [true, false] :exclusive (nil) Overrides default and makes the range exclusive -
|
76
94
|
# equivalent to passing both `:exclusive_min` and `:exclusive_max`
|
77
95
|
# @option options [true, false] :exclusive_min (nil) Overrides default and makes the minimum exclusive
|
78
96
|
# @option options [true, false] :exclusive_max (nil) Overrides default and makes the maximum exclusive
|
79
|
-
#
|
97
|
+
#
|
80
98
|
# @return [self] query state with range filter applied
|
81
|
-
#
|
99
|
+
#
|
82
100
|
# @example Adding a range filter
|
83
101
|
# query.where.range(:my_range_field,
|
84
102
|
# min: 33,
|
85
103
|
# exclusive: true
|
86
104
|
# )
|
87
105
|
def range(field, options = {})
|
88
|
-
options
|
89
|
-
options[:should] = true if should?
|
106
|
+
options = merge_state(options)
|
90
107
|
base.where_builder.add_range(field, options)
|
91
108
|
self
|
92
109
|
end
|
93
110
|
|
94
|
-
#
|
111
|
+
#
|
95
112
|
# Adds a geo distance filter to the current context.
|
96
113
|
# Documents must have a `geo_point` field that is within
|
97
114
|
# the specified distance of the passed parameters.
|
98
|
-
#
|
115
|
+
#
|
99
116
|
# @param field [String, Symbol] The field this filter will be applied to.
|
100
117
|
# @param options = {} [Hash] Options for the geo distance filter
|
101
|
-
# @option options [String] :distance (nil) The maximum distance from the specified origin.
|
118
|
+
# @option options [String] :distance (nil) The maximum distance from the specified origin.
|
102
119
|
# Use an Elastic distance format such as `'21mi'` or `'37km'`
|
103
120
|
# @option options [Float] :lat (nil) The latitude of the origin point. Can also be specified as `:latitude`
|
104
|
-
# @option options [Float] :lng (nil) The longitude of the origin point.
|
121
|
+
# @option options [Float] :lng (nil) The longitude of the origin point.
|
105
122
|
# Can also be specified as `:lon` or `:longitude`
|
106
|
-
#
|
123
|
+
#
|
107
124
|
# @return [self] query state with geo distance filter applied
|
108
|
-
#
|
125
|
+
#
|
109
126
|
# @example Searching by distance from a point
|
110
127
|
# query.where.geo(:coords,
|
111
128
|
# distance: '27km',
|
@@ -114,50 +131,49 @@ module Stretchy
|
|
114
131
|
# )
|
115
132
|
def geo(field, options = {})
|
116
133
|
distance = options[:distance]
|
117
|
-
options
|
118
|
-
options[:should] = true if should?
|
134
|
+
options = merge_state(options)
|
119
135
|
base.where_builder.add_geo(field, distance, options)
|
120
136
|
self
|
121
137
|
end
|
122
138
|
|
123
|
-
#
|
139
|
+
#
|
124
140
|
# Used for passing strings or symbols in a `.where`
|
125
141
|
# method, and using the un-analyzed Terms filter instead
|
126
142
|
# of an analyzed and parsed Match Query.
|
127
|
-
#
|
143
|
+
#
|
128
144
|
# This would be useful if you have a set of specific
|
129
145
|
# strings a field could be in, such as:
|
130
146
|
# `role: ['admin_user', 'company_manager']`
|
131
147
|
# and you want to query for those exact strings without
|
132
148
|
# the usual downcase / punctuation removal analysis.
|
133
|
-
#
|
149
|
+
#
|
134
150
|
# **CAUTION:** The keys indexed by elastic may be analyzed -
|
135
151
|
# downcased, punctuation removed, etc. Using a terms filter
|
136
152
|
# in this case _will not work_ . Hence the default of using
|
137
153
|
# a match query for strings and symbols instead.
|
138
|
-
#
|
139
|
-
# @param options = {} [Hash] Options to be passed to the
|
154
|
+
#
|
155
|
+
# @param options = {} [Hash] Options to be passed to the
|
140
156
|
# {WhereClause}
|
141
|
-
#
|
157
|
+
#
|
142
158
|
# @return [WhereClause] query state with filters applied
|
143
|
-
#
|
159
|
+
#
|
144
160
|
# @example Querying for exact terms
|
145
161
|
# query.where.terms(
|
146
162
|
# status_field: 'working_fine_today',
|
147
163
|
# number: 27,
|
148
164
|
# date: Date.today
|
149
165
|
# )
|
150
|
-
#
|
166
|
+
#
|
151
167
|
# @example Not matching exact terms
|
152
168
|
# query.where.not.terms(
|
153
169
|
# email: 'my.email@company.com'
|
154
170
|
# )
|
155
|
-
#
|
171
|
+
#
|
156
172
|
# @example Should match exact terms
|
157
173
|
# query.should.terms(
|
158
174
|
# hacker_alias: '!!ic3y.h0t~~!'
|
159
175
|
# )
|
160
|
-
#
|
176
|
+
#
|
161
177
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-terms-filter.html Elasticsearch Terms Filter
|
162
178
|
def terms(params = {}, options = {})
|
163
179
|
options[:exact] = true
|
@@ -166,17 +182,17 @@ module Stretchy
|
|
166
182
|
end
|
167
183
|
alias :exact :terms
|
168
184
|
|
169
|
-
#
|
170
|
-
# Switches current state to inverted. Options passed
|
185
|
+
#
|
186
|
+
# Switches current state to inverted. Options passed
|
171
187
|
# here are equivalent to those passed to {#initialize},
|
172
188
|
# except documents *must not* match these filters.
|
173
|
-
#
|
189
|
+
#
|
174
190
|
# Can be chained with {#should} to produce inverted should queries
|
175
|
-
#
|
191
|
+
#
|
176
192
|
# @param params = {} [Hash] params to filter on
|
177
|
-
#
|
193
|
+
#
|
178
194
|
# @return [WhereClause] inverted query state with not filters applied.
|
179
|
-
#
|
195
|
+
#
|
180
196
|
# @example Inverting filters
|
181
197
|
# query.where.not(
|
182
198
|
# must_exist: nil,
|
@@ -184,7 +200,7 @@ module Stretchy
|
|
184
200
|
# not_in: [45, 67, 99],
|
185
201
|
# not_in_range: 89..23
|
186
202
|
# )
|
187
|
-
#
|
203
|
+
#
|
188
204
|
# @example Inverted should filters
|
189
205
|
# query.should.not(
|
190
206
|
# match_field: [:these, "params"]
|
@@ -195,31 +211,31 @@ module Stretchy
|
|
195
211
|
self
|
196
212
|
end
|
197
213
|
|
198
|
-
#
|
214
|
+
#
|
199
215
|
# Switches the current state to `should`. Options passed
|
200
216
|
# here are equivalent to those passed to {#initialize},
|
201
217
|
# except documents which do not match are still returned
|
202
218
|
# with a lower score than documents which do match.
|
203
|
-
#
|
219
|
+
#
|
204
220
|
# Can be chained with {#not} to produce inverted should queries
|
205
|
-
#
|
221
|
+
#
|
206
222
|
# **CAUTION:** Documents that don't match at least one `should`
|
207
223
|
# clause will not be returned.
|
208
|
-
#
|
224
|
+
#
|
209
225
|
# @param params = {} [Hash] params to filter on
|
210
|
-
#
|
226
|
+
#
|
211
227
|
# @return [WhereClause] should query state with should filters applied
|
212
|
-
#
|
228
|
+
#
|
213
229
|
# @example Specifying should params
|
214
230
|
# query.should(
|
215
231
|
# field: [99, 27]
|
216
232
|
# )
|
217
|
-
#
|
233
|
+
#
|
218
234
|
# @example Inverted should params
|
219
235
|
# query.should.not(
|
220
236
|
# exists_field: nil
|
221
|
-
# )
|
222
|
-
#
|
237
|
+
# )
|
238
|
+
#
|
223
239
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/1.4/query-dsl-bool-query.html Elasticsearch Bool Query docs (bool filter just references this)
|
224
240
|
def should(params = {}, options = {})
|
225
241
|
@inverse = false
|
@@ -228,12 +244,12 @@ module Stretchy
|
|
228
244
|
self
|
229
245
|
end
|
230
246
|
|
231
|
-
#
|
247
|
+
#
|
232
248
|
# Converts the current context into a boost to
|
233
249
|
# be passed into a {FunctionScoreQuery}.
|
234
|
-
#
|
250
|
+
#
|
235
251
|
# @param weight = nil [Numeric] A weight for the {FunctionScoreQuery}
|
236
|
-
#
|
252
|
+
#
|
237
253
|
# @return [Boosts::FilterBoost] A boost including all the current filters
|
238
254
|
def to_boost(weight = nil)
|
239
255
|
weight ||= Stretchy::Boosts::FilterBoost::DEFAULT_WEIGHT
|
@@ -248,7 +264,7 @@ module Stretchy
|
|
248
264
|
),
|
249
265
|
weight: weight
|
250
266
|
)
|
251
|
-
|
267
|
+
|
252
268
|
elsif base.match_builder.any?
|
253
269
|
Stretchy::Boosts::FilterBoost.new(
|
254
270
|
filter: Stretchy::Filters::QueryFilter.new(
|
@@ -266,13 +282,13 @@ module Stretchy
|
|
266
282
|
end
|
267
283
|
|
268
284
|
private
|
269
|
-
|
285
|
+
|
270
286
|
def add_params(params = {}, options = {})
|
271
287
|
params.each do |field, param|
|
272
288
|
# if it is an array, process each param
|
273
289
|
# separately - ensures string & symbols
|
274
290
|
# always go into .match_builder
|
275
|
-
|
291
|
+
|
276
292
|
if param.is_a?(Array)
|
277
293
|
param.each{|p| add_param(field, p, options) }
|
278
294
|
else
|
@@ -295,4 +311,4 @@ module Stretchy
|
|
295
311
|
|
296
312
|
end
|
297
313
|
end
|
298
|
-
end
|
314
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'stretchy/filters/base'
|
2
|
+
|
3
|
+
module Stretchy
|
4
|
+
module Filters
|
5
|
+
|
6
|
+
# This class allows using arbitrary JSON as a filter.
|
7
|
+
# This way, users can make use of elasticsearch features
|
8
|
+
# not yet supported by Stretchy
|
9
|
+
|
10
|
+
class ParamsFilter < Base
|
11
|
+
|
12
|
+
attribute :params, Hash
|
13
|
+
|
14
|
+
validations do
|
15
|
+
rule :params, :required
|
16
|
+
end
|
17
|
+
|
18
|
+
def initialize(params)
|
19
|
+
@params = params
|
20
|
+
validate!
|
21
|
+
end
|
22
|
+
|
23
|
+
alias :to_search :params
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/stretchy/filters.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'stretchy/queries/base'
|
2
|
+
|
3
|
+
module Stretchy
|
4
|
+
module Queries
|
5
|
+
class ParamsQuery < Base
|
6
|
+
|
7
|
+
attribute :params, Hash
|
8
|
+
|
9
|
+
validations do
|
10
|
+
rule :params, :required
|
11
|
+
end
|
12
|
+
|
13
|
+
def initialize(params)
|
14
|
+
@params = params
|
15
|
+
end
|
16
|
+
|
17
|
+
alias :to_search :params
|
18
|
+
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/stretchy/queries.rb
CHANGED
data/lib/stretchy/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stretchy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.
|
4
|
+
version: 0.4.7
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- agius
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-06-
|
11
|
+
date: 2015-06-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: elasticsearch
|
@@ -171,9 +171,11 @@ executables: []
|
|
171
171
|
extensions: []
|
172
172
|
extra_rdoc_files: []
|
173
173
|
files:
|
174
|
+
- ".editorconfig"
|
174
175
|
- ".gitignore"
|
175
176
|
- ".ruby-version"
|
176
177
|
- ".yardopts"
|
178
|
+
- CONTRIBUTING.md
|
177
179
|
- Gemfile
|
178
180
|
- README.md
|
179
181
|
- Rakefile
|
@@ -211,6 +213,7 @@ files:
|
|
211
213
|
- lib/stretchy/filters/geo_filter.rb
|
212
214
|
- lib/stretchy/filters/not_filter.rb
|
213
215
|
- lib/stretchy/filters/or_filter.rb
|
216
|
+
- lib/stretchy/filters/params_filter.rb
|
214
217
|
- lib/stretchy/filters/query_filter.rb
|
215
218
|
- lib/stretchy/filters/range_filter.rb
|
216
219
|
- lib/stretchy/filters/terms_filter.rb
|
@@ -222,6 +225,7 @@ files:
|
|
222
225
|
- lib/stretchy/queries/match_all_query.rb
|
223
226
|
- lib/stretchy/queries/match_query.rb
|
224
227
|
- lib/stretchy/queries/more_like_this_query.rb
|
228
|
+
- lib/stretchy/queries/params_query.rb
|
225
229
|
- lib/stretchy/results.rb
|
226
230
|
- lib/stretchy/results/base.rb
|
227
231
|
- lib/stretchy/results/null_results.rb
|