stretchy-model 0.4.0 → 0.6.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/.rspec +1 -1
- data/README.md +19 -84
- data/lib/rails/instrumentation/railtie.rb +2 -0
- data/lib/stretchy/associations.rb +155 -15
- data/lib/stretchy/attributes/type/array.rb +20 -0
- data/lib/stretchy/attributes/type/base.rb +42 -0
- data/lib/stretchy/attributes/type/binary.rb +45 -0
- data/lib/stretchy/attributes/type/boolean.rb +48 -0
- data/lib/stretchy/attributes/type/completion.rb +25 -0
- data/lib/stretchy/attributes/type/constant_keyword.rb +38 -0
- data/lib/stretchy/attributes/type/date_time.rb +35 -0
- data/lib/stretchy/attributes/type/dense_vector.rb +59 -0
- data/lib/stretchy/attributes/type/flattened.rb +31 -0
- data/lib/stretchy/attributes/type/geo_point.rb +27 -0
- data/lib/stretchy/attributes/type/geo_shape.rb +27 -0
- data/lib/stretchy/attributes/type/hash.rb +40 -0
- data/lib/stretchy/attributes/type/histogram.rb +7 -0
- data/lib/stretchy/attributes/type/ip.rb +29 -0
- data/lib/stretchy/attributes/type/join.rb +22 -0
- data/lib/stretchy/attributes/type/keyword.rb +36 -10
- data/lib/stretchy/attributes/type/match_only_text.rb +8 -0
- data/lib/stretchy/attributes/type/nested.rb +25 -0
- data/lib/stretchy/attributes/type/numeric/base.rb +32 -0
- data/lib/stretchy/attributes/type/numeric/byte.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/double.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/float.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/half_float.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/integer.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/long.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/scaled_float.rb +23 -0
- data/lib/stretchy/attributes/type/numeric/short.rb +7 -0
- data/lib/stretchy/attributes/type/numeric/unsigned_long.rb +7 -0
- data/lib/stretchy/attributes/type/percolator.rb +23 -0
- data/lib/stretchy/attributes/type/point.rb +24 -0
- data/lib/stretchy/attributes/type/range/base.rb +9 -0
- data/lib/stretchy/attributes/type/range/date_range.rb +17 -0
- data/lib/stretchy/attributes/type/range/double_range.rb +17 -0
- data/lib/stretchy/attributes/type/range/float_range.rb +16 -0
- data/lib/stretchy/attributes/type/range/integer_range.rb +16 -0
- data/lib/stretchy/attributes/type/range/ip_range.rb +16 -0
- data/lib/stretchy/attributes/type/range/long_range.rb +16 -0
- data/lib/stretchy/attributes/type/rank_feature.rb +21 -0
- data/lib/stretchy/attributes/type/rank_features.rb +24 -0
- data/lib/stretchy/attributes/type/search_as_you_type.rb +30 -0
- data/lib/stretchy/attributes/type/shape.rb +24 -0
- data/lib/stretchy/attributes/type/sparse_vector.rb +37 -0
- data/lib/stretchy/attributes/type/string.rb +7 -0
- data/lib/stretchy/attributes/type/text.rb +51 -0
- data/lib/stretchy/attributes/type/token_count.rb +26 -0
- data/lib/stretchy/attributes/type/version.rb +21 -0
- data/lib/stretchy/attributes/type/wildcard.rb +35 -0
- data/lib/stretchy/attributes.rb +68 -2
- data/lib/stretchy/common.rb +5 -5
- data/lib/stretchy/delegation/gateway_delegation.rb +9 -5
- data/lib/stretchy/model/serialization.rb +1 -0
- data/lib/stretchy/querying.rb +4 -4
- data/lib/stretchy/record.rb +9 -10
- data/lib/stretchy/relation.rb +11 -17
- data/lib/stretchy/relations/finder_methods.rb +19 -2
- data/lib/stretchy/relations/merger.rb +5 -1
- data/lib/stretchy/relations/query_builder.rb +32 -3
- data/lib/stretchy/relations/query_methods.rb +66 -2
- data/lib/stretchy/scoping/named.rb +1 -1
- data/lib/stretchy/shared_scopes.rb +1 -1
- data/lib/stretchy/version.rb +1 -1
- data/lib/stretchy.rb +5 -3
- data/lib/stretchy_model.rb +9 -0
- metadata +49 -4
- data/lib/active_model/type/array.rb +0 -13
- data/lib/active_model/type/hash.rb +0 -15
@@ -2,11 +2,12 @@ module Stretchy
|
|
2
2
|
module Relations
|
3
3
|
class QueryBuilder
|
4
4
|
|
5
|
-
attr_reader :structure, :values, :attribute_types
|
5
|
+
attr_reader :structure, :values, :attribute_types, :default_size
|
6
6
|
|
7
7
|
def initialize(values, attribute_types = nil)
|
8
8
|
@attribute_types = attribute_types
|
9
9
|
@structure = Jbuilder.new ignore_nil: true
|
10
|
+
@default_size = values.delete(:default_size)
|
10
11
|
@values = values
|
11
12
|
end
|
12
13
|
|
@@ -38,6 +39,10 @@ module Stretchy
|
|
38
39
|
@shoulds ||= compact_where(values[:should])
|
39
40
|
end
|
40
41
|
|
42
|
+
def regexes
|
43
|
+
@regexes ||= values[:regexp]
|
44
|
+
end
|
45
|
+
|
41
46
|
def fields
|
42
47
|
values[:field]
|
43
48
|
end
|
@@ -88,7 +93,7 @@ module Stretchy
|
|
88
93
|
private
|
89
94
|
|
90
95
|
def missing_bool_query?
|
91
|
-
query.nil? && must_nots.nil? && shoulds.nil?
|
96
|
+
query.nil? && must_nots.nil? && shoulds.nil? && regexes.nil?
|
92
97
|
end
|
93
98
|
|
94
99
|
def missing_query_string?
|
@@ -102,7 +107,12 @@ module Stretchy
|
|
102
107
|
def build_query
|
103
108
|
return if missing_bool_query? && missing_query_string? && missing_query_filter?
|
104
109
|
structure.query do
|
110
|
+
structure.regexp do
|
111
|
+
build_regexp unless regexes.nil?
|
112
|
+
end
|
113
|
+
|
105
114
|
structure.bool do
|
115
|
+
|
106
116
|
structure.must query unless missing_bool_query?
|
107
117
|
structure.must_not must_nots unless must_nots.nil?
|
108
118
|
structure.set! :should, shoulds unless shoulds.nil?
|
@@ -120,6 +130,14 @@ module Stretchy
|
|
120
130
|
end.with_indifferent_access
|
121
131
|
end
|
122
132
|
|
133
|
+
def build_regexp
|
134
|
+
regexes.each do |args|
|
135
|
+
target_field = args.first.keys.first
|
136
|
+
value_field = args.first.values.first
|
137
|
+
structure.set! target_field, args.last.merge(value: value_field)
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
123
141
|
def build_filtered_query
|
124
142
|
structure.filter do
|
125
143
|
structure.or do
|
@@ -157,7 +175,13 @@ module Stretchy
|
|
157
175
|
structure.highlight do
|
158
176
|
structure.fields do
|
159
177
|
highlights.each do |highlight|
|
160
|
-
|
178
|
+
if highlight.is_a?(String) || highlight.is_a?(Symbol)
|
179
|
+
structure.set! highlight, {}
|
180
|
+
elsif highlight.is_a?(Hash)
|
181
|
+
highlight.each_pair do |k,v|
|
182
|
+
structure.set! k, v
|
183
|
+
end
|
184
|
+
end
|
161
185
|
end
|
162
186
|
end
|
163
187
|
end
|
@@ -185,6 +209,11 @@ module Stretchy
|
|
185
209
|
end
|
186
210
|
|
187
211
|
def extra_search_options
|
212
|
+
unless self.count?
|
213
|
+
values[:size] = size.present? ? size : values[:default_size]
|
214
|
+
else
|
215
|
+
values[:size] = nil
|
216
|
+
end
|
188
217
|
[:size].inject(Hash.new) { |h,k| h[k] = self.send(k) unless self.send(k).nil?; h}
|
189
218
|
end
|
190
219
|
|
@@ -18,7 +18,8 @@ module Stretchy
|
|
18
18
|
:filter_query,
|
19
19
|
:or_filter,
|
20
20
|
:extending,
|
21
|
-
:skip_callbacks
|
21
|
+
:skip_callbacks,
|
22
|
+
:regexp
|
22
23
|
]
|
23
24
|
|
24
25
|
SINGLE_VALUE_METHODS = [:size]
|
@@ -173,6 +174,16 @@ module Stretchy
|
|
173
174
|
# }
|
174
175
|
# }
|
175
176
|
#
|
177
|
+
# .where acts as a convienence method for adding conditions to the query. It can also be used to add
|
178
|
+
# range , regex, terms, and id queries through shorthand parameters.
|
179
|
+
#
|
180
|
+
# @example
|
181
|
+
# Model.where(price: {gte: 10, lte: 20})
|
182
|
+
# Model.where(age: 19..33)
|
183
|
+
# Model.where(color: /gr(a|e)y/)
|
184
|
+
# Model.where(id: [10, 22, 18])
|
185
|
+
# Model.where(names: ['John', 'Jane'])
|
186
|
+
#
|
176
187
|
# @return [ActiveRecord::Relation, WhereChain] a new relation, which reflects the conditions, or a WhereChain if opts is :chain
|
177
188
|
# @see #must
|
178
189
|
def where(opts = :chain, *rest)
|
@@ -181,7 +192,28 @@ module Stretchy
|
|
181
192
|
elsif opts.blank?
|
182
193
|
self
|
183
194
|
else
|
184
|
-
|
195
|
+
opts.each do |key, value|
|
196
|
+
case value
|
197
|
+
when Range
|
198
|
+
between(value, key)
|
199
|
+
when Hash
|
200
|
+
filter_query(:range, key => value) if value.keys.any? { |k| [:gte, :lte, :gt, :lt].include?(k) }
|
201
|
+
when Regexp
|
202
|
+
regexp(Hash[key, value])
|
203
|
+
when Array
|
204
|
+
# handle ID queries
|
205
|
+
# if [:id, :_id].include?(key)
|
206
|
+
|
207
|
+
# else
|
208
|
+
spawn.where!(opts, *rest)
|
209
|
+
# end
|
210
|
+
else
|
211
|
+
spawn.where!(opts, *rest)
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
215
|
+
self
|
216
|
+
|
185
217
|
end
|
186
218
|
end
|
187
219
|
|
@@ -199,6 +231,38 @@ module Stretchy
|
|
199
231
|
# @see #where
|
200
232
|
alias :must :where
|
201
233
|
|
234
|
+
# Adds a regexp condition to the query.
|
235
|
+
#
|
236
|
+
# @param field [Hash] the field to filter by and the Regexp to match
|
237
|
+
# @param opts [Hash] additional options for the regexp query
|
238
|
+
# - :flags [String] the flags to use for the regexp query (e.g. 'ALL')
|
239
|
+
# - :use_keyword [Boolean] whether to use the .keyword field for the regexp query. Default: true
|
240
|
+
# - :case_insensitive [Boolean] whether to use case insensitive matching. If the regexp has ignore case flag `/regex/i`, this is automatically set to true
|
241
|
+
# - :max_determinized_states [Integer] the maximum number of states that the regexp query can produce
|
242
|
+
# - :rewrite [String] the rewrite method to use for the regexp query
|
243
|
+
#
|
244
|
+
#
|
245
|
+
# @example
|
246
|
+
# Model.regexp(:name, /john|jane/)
|
247
|
+
# Model.regexp(:name, /john|jane/i)
|
248
|
+
# Model.regexp(:name, /john|jane/i, flags: 'ALL')
|
249
|
+
#
|
250
|
+
# @return [Stretchy::Relation] a new relation, which reflects the regexp condition
|
251
|
+
# @see #where
|
252
|
+
def regexp(args)
|
253
|
+
spawn.regexp!(args)
|
254
|
+
end
|
255
|
+
|
256
|
+
def regexp!(args) # :nodoc:
|
257
|
+
args = args.to_a
|
258
|
+
target_field, regex = args.shift
|
259
|
+
opts = args.to_h
|
260
|
+
opts.reverse_merge!(use_keyword: true)
|
261
|
+
target_field = "#{target_field}.keyword" if opts.delete(:use_keyword)
|
262
|
+
opts.merge!(case_insensitive: true) if regex.casefold?
|
263
|
+
self.regexp_values += [[Hash[target_field, regex.source], opts]]
|
264
|
+
self
|
265
|
+
end
|
202
266
|
|
203
267
|
|
204
268
|
|
@@ -4,7 +4,7 @@ module Stretchy
|
|
4
4
|
|
5
5
|
included do
|
6
6
|
|
7
|
-
scope :between,
|
7
|
+
scope :between, ->(range, range_field = "created_at") { filter_query(:range, range_field => {gte: range.begin, lte: range.end}) }
|
8
8
|
scope :using_time_based_indices, lambda { |range| search_options(index: time_based_indices(range)) }
|
9
9
|
|
10
10
|
end
|
data/lib/stretchy/version.rb
CHANGED
data/lib/stretchy.rb
CHANGED
@@ -7,14 +7,11 @@ require 'elasticsearch/model'
|
|
7
7
|
require 'elasticsearch/persistence'
|
8
8
|
require 'active_model'
|
9
9
|
require 'active_support/all'
|
10
|
-
require 'active_model/type/array'
|
11
|
-
require 'active_model/type/hash'
|
12
10
|
|
13
11
|
require_relative "stretchy/version"
|
14
12
|
require_relative "rails/instrumentation/railtie" if defined?(Rails)
|
15
13
|
|
16
14
|
|
17
|
-
|
18
15
|
module Stretchy
|
19
16
|
|
20
17
|
def self.loader
|
@@ -23,6 +20,7 @@ module Stretchy
|
|
23
20
|
loader.tag = File.basename(__FILE__, ".rb")
|
24
21
|
loader.inflector = Zeitwerk::GemInflector.new(__FILE__)
|
25
22
|
loader.push_dir(__dir__)
|
23
|
+
loader.inflector.inflect("ip" => "IP")
|
26
24
|
loader
|
27
25
|
end
|
28
26
|
end
|
@@ -32,6 +30,10 @@ module Stretchy
|
|
32
30
|
Stretchy::Attributes.register!
|
33
31
|
end
|
34
32
|
|
33
|
+
def self.instrument!
|
34
|
+
Stretchy::Delegation::GatewayDelegation.send(:include, Rails::Instrumentation::Publishers::Record)
|
35
|
+
end
|
36
|
+
|
35
37
|
module Errors
|
36
38
|
class QueryOptionMissing < StandardError; end
|
37
39
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: stretchy-model
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Spencer Markowski
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-03-
|
11
|
+
date: 2024-03-15 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: zeitwerk
|
@@ -224,8 +224,6 @@ files:
|
|
224
224
|
- containers/Dockerfile.elasticsearch
|
225
225
|
- containers/Dockerfile.opensearch
|
226
226
|
- docker-compose.yml
|
227
|
-
- lib/active_model/type/array.rb
|
228
|
-
- lib/active_model/type/hash.rb
|
229
227
|
- lib/rails/instrumentation/publishers.rb
|
230
228
|
- lib/rails/instrumentation/railtie.rb
|
231
229
|
- lib/stretchy.rb
|
@@ -234,7 +232,53 @@ files:
|
|
234
232
|
- lib/stretchy/associations/elastic_relation.rb
|
235
233
|
- lib/stretchy/attributes.rb
|
236
234
|
- lib/stretchy/attributes/transformers/keyword_transformer.rb
|
235
|
+
- lib/stretchy/attributes/type/array.rb
|
236
|
+
- lib/stretchy/attributes/type/base.rb
|
237
|
+
- lib/stretchy/attributes/type/binary.rb
|
238
|
+
- lib/stretchy/attributes/type/boolean.rb
|
239
|
+
- lib/stretchy/attributes/type/completion.rb
|
240
|
+
- lib/stretchy/attributes/type/constant_keyword.rb
|
241
|
+
- lib/stretchy/attributes/type/date_time.rb
|
242
|
+
- lib/stretchy/attributes/type/dense_vector.rb
|
243
|
+
- lib/stretchy/attributes/type/flattened.rb
|
244
|
+
- lib/stretchy/attributes/type/geo_point.rb
|
245
|
+
- lib/stretchy/attributes/type/geo_shape.rb
|
246
|
+
- lib/stretchy/attributes/type/hash.rb
|
247
|
+
- lib/stretchy/attributes/type/histogram.rb
|
248
|
+
- lib/stretchy/attributes/type/ip.rb
|
249
|
+
- lib/stretchy/attributes/type/join.rb
|
237
250
|
- lib/stretchy/attributes/type/keyword.rb
|
251
|
+
- lib/stretchy/attributes/type/match_only_text.rb
|
252
|
+
- lib/stretchy/attributes/type/nested.rb
|
253
|
+
- lib/stretchy/attributes/type/numeric/base.rb
|
254
|
+
- lib/stretchy/attributes/type/numeric/byte.rb
|
255
|
+
- lib/stretchy/attributes/type/numeric/double.rb
|
256
|
+
- lib/stretchy/attributes/type/numeric/float.rb
|
257
|
+
- lib/stretchy/attributes/type/numeric/half_float.rb
|
258
|
+
- lib/stretchy/attributes/type/numeric/integer.rb
|
259
|
+
- lib/stretchy/attributes/type/numeric/long.rb
|
260
|
+
- lib/stretchy/attributes/type/numeric/scaled_float.rb
|
261
|
+
- lib/stretchy/attributes/type/numeric/short.rb
|
262
|
+
- lib/stretchy/attributes/type/numeric/unsigned_long.rb
|
263
|
+
- lib/stretchy/attributes/type/percolator.rb
|
264
|
+
- lib/stretchy/attributes/type/point.rb
|
265
|
+
- lib/stretchy/attributes/type/range/base.rb
|
266
|
+
- lib/stretchy/attributes/type/range/date_range.rb
|
267
|
+
- lib/stretchy/attributes/type/range/double_range.rb
|
268
|
+
- lib/stretchy/attributes/type/range/float_range.rb
|
269
|
+
- lib/stretchy/attributes/type/range/integer_range.rb
|
270
|
+
- lib/stretchy/attributes/type/range/ip_range.rb
|
271
|
+
- lib/stretchy/attributes/type/range/long_range.rb
|
272
|
+
- lib/stretchy/attributes/type/rank_feature.rb
|
273
|
+
- lib/stretchy/attributes/type/rank_features.rb
|
274
|
+
- lib/stretchy/attributes/type/search_as_you_type.rb
|
275
|
+
- lib/stretchy/attributes/type/shape.rb
|
276
|
+
- lib/stretchy/attributes/type/sparse_vector.rb
|
277
|
+
- lib/stretchy/attributes/type/string.rb
|
278
|
+
- lib/stretchy/attributes/type/text.rb
|
279
|
+
- lib/stretchy/attributes/type/token_count.rb
|
280
|
+
- lib/stretchy/attributes/type/version.rb
|
281
|
+
- lib/stretchy/attributes/type/wildcard.rb
|
238
282
|
- lib/stretchy/common.rb
|
239
283
|
- lib/stretchy/delegation/delegate_cache.rb
|
240
284
|
- lib/stretchy/delegation/gateway_delegation.rb
|
@@ -263,6 +307,7 @@ files:
|
|
263
307
|
- lib/stretchy/shared_scopes.rb
|
264
308
|
- lib/stretchy/utils.rb
|
265
309
|
- lib/stretchy/version.rb
|
310
|
+
- lib/stretchy_model.rb
|
266
311
|
- sig/stretchy.rbs
|
267
312
|
- stretchy-model/lib/stretchy-model.rb
|
268
313
|
- stretchy.logo.png
|