chewy 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -3
- data/CHANGELOG.md +43 -1
- data/Gemfile +3 -0
- data/README.md +49 -11
- data/chewy.gemspec +1 -2
- data/gemfiles/Gemfile.rails-3.2 +1 -0
- data/gemfiles/Gemfile.rails-4.0 +1 -0
- data/lib/chewy.rb +8 -2
- data/lib/chewy/backports/deep_dup.rb +46 -0
- data/lib/chewy/backports/duplicable.rb +90 -0
- data/lib/chewy/config.rb +33 -6
- data/lib/chewy/errors.rb +1 -1
- data/lib/chewy/fields/base.rb +19 -7
- data/lib/chewy/fields/root.rb +13 -0
- data/lib/chewy/index/actions.rb +14 -6
- data/lib/chewy/index/search.rb +3 -2
- data/lib/chewy/query.rb +131 -17
- data/lib/chewy/query/compose.rb +27 -17
- data/lib/chewy/query/criteria.rb +34 -22
- data/lib/chewy/query/loading.rb +94 -10
- data/lib/chewy/query/nodes/exists.rb +1 -1
- data/lib/chewy/query/nodes/has_relation.rb +1 -1
- data/lib/chewy/query/nodes/missing.rb +1 -1
- data/lib/chewy/query/pagination.rb +8 -38
- data/lib/chewy/query/pagination/kaminari.rb +37 -0
- data/lib/chewy/runtime.rb +9 -0
- data/lib/chewy/runtime/version.rb +25 -0
- data/lib/chewy/type/adapter/active_record.rb +21 -7
- data/lib/chewy/type/adapter/base.rb +1 -1
- data/lib/chewy/type/adapter/object.rb +9 -6
- data/lib/chewy/type/import.rb +7 -4
- data/lib/chewy/type/mapping.rb +9 -9
- data/lib/chewy/type/wrapper.rb +1 -1
- data/lib/chewy/version.rb +1 -1
- data/lib/tasks/chewy.rake +40 -21
- data/spec/chewy/config_spec.rb +1 -1
- data/spec/chewy/fields/base_spec.rb +273 -8
- data/spec/chewy/index/actions_spec.rb +1 -2
- data/spec/chewy/index/aliases_spec.rb +0 -1
- data/spec/chewy/index/search_spec.rb +0 -8
- data/spec/chewy/index/settings_spec.rb +0 -2
- data/spec/chewy/index_spec.rb +0 -2
- data/spec/chewy/query/criteria_spec.rb +85 -18
- data/spec/chewy/query/loading_spec.rb +26 -9
- data/spec/chewy/query/nodes/and_spec.rb +2 -2
- data/spec/chewy/query/nodes/exists_spec.rb +6 -6
- data/spec/chewy/query/nodes/missing_spec.rb +4 -4
- data/spec/chewy/query/nodes/or_spec.rb +2 -2
- data/spec/chewy/query/pagination/kaminari_spec.rb +55 -0
- data/spec/chewy/query/pagination_spec.rb +15 -22
- data/spec/chewy/query_spec.rb +121 -52
- data/spec/chewy/rspec/update_index_spec.rb +0 -1
- data/spec/chewy/runtime/version_spec.rb +48 -0
- data/spec/chewy/runtime_spec.rb +9 -0
- data/spec/chewy/type/adapter/active_record_spec.rb +52 -0
- data/spec/chewy/type/adapter/object_spec.rb +33 -0
- data/spec/chewy/type/import_spec.rb +1 -3
- data/spec/chewy/type/mapping_spec.rb +4 -6
- data/spec/chewy/type/observe_spec.rb +0 -2
- data/spec/chewy/type/wrapper_spec.rb +0 -2
- data/spec/chewy/type_spec.rb +26 -5
- data/spec/chewy_spec.rb +0 -2
- data/spec/spec_helper.rb +2 -2
- metadata +15 -21
- data/lib/chewy/fields/default.rb +0 -10
- data/spec/chewy/fields/default_spec.rb +0 -6
data/lib/chewy/errors.rb
CHANGED
data/lib/chewy/fields/base.rb
CHANGED
@@ -4,23 +4,33 @@ module Chewy
|
|
4
4
|
attr_reader :name, :options, :value
|
5
5
|
|
6
6
|
def initialize(name, options = {})
|
7
|
-
@name, @options, @nested = name.to_sym, options, {}
|
7
|
+
@name, @options, @nested = name.to_sym, options.deep_symbolize_keys, {}
|
8
8
|
@value = @options.delete(:value)
|
9
9
|
end
|
10
10
|
|
11
11
|
def multi_field?
|
12
|
-
|
12
|
+
nested.any? && !object_field?
|
13
|
+
end
|
14
|
+
|
15
|
+
def object_field?
|
16
|
+
(nested.any? && options[:type].blank?) || options[:type].to_s == 'object'
|
17
|
+
end
|
18
|
+
|
19
|
+
def root_field?
|
20
|
+
false
|
13
21
|
end
|
14
22
|
|
15
23
|
def compose(object)
|
16
24
|
result = if value && value.is_a?(Proc)
|
17
25
|
value.arity == 0 ? object.instance_exec(&value) : value.call(object)
|
26
|
+
elsif object.is_a?(Hash)
|
27
|
+
object[name] || object[name.to_s]
|
18
28
|
else
|
19
29
|
object.send(name)
|
20
30
|
end
|
21
31
|
|
22
|
-
result = if result.
|
23
|
-
result.map { |object| nested_compose(object) }
|
32
|
+
result = if result.respond_to?(:to_ary)
|
33
|
+
result.to_ary.map { |object| nested_compose(object) }
|
24
34
|
else
|
25
35
|
nested_compose(result)
|
26
36
|
end if nested.any? && !multi_field?
|
@@ -37,16 +47,18 @@ module Chewy
|
|
37
47
|
end
|
38
48
|
|
39
49
|
def mappings_hash
|
40
|
-
|
50
|
+
mapping = nested.any? ? {
|
41
51
|
(multi_field? ? :fields : :properties) => nested.values.map(&:mappings_hash).inject(:merge)
|
42
52
|
} : {}
|
43
|
-
|
53
|
+
mapping.reverse_merge!(options)
|
54
|
+
mapping.reverse_merge!(type: (nested.any? ? 'object' : 'string')) unless root_field?
|
55
|
+
{name => mapping}
|
44
56
|
end
|
45
57
|
|
46
58
|
private
|
47
59
|
|
48
60
|
def nested_compose(value)
|
49
|
-
nested.values.map { |field| field.compose(value) }.inject(:merge)
|
61
|
+
nested.values.map { |field| field.compose(value) if value }.compact.inject(:merge)
|
50
62
|
end
|
51
63
|
end
|
52
64
|
end
|
data/lib/chewy/fields/root.rb
CHANGED
@@ -6,9 +6,22 @@ module Chewy
|
|
6
6
|
def initialize(name, options = {})
|
7
7
|
options.reverse_merge!(value: ->(_){_})
|
8
8
|
super(name, options)
|
9
|
+
options.delete(:type)
|
9
10
|
@dynamic_templates = []
|
10
11
|
end
|
11
12
|
|
13
|
+
def multi_field?
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def object_field?
|
18
|
+
true
|
19
|
+
end
|
20
|
+
|
21
|
+
def root_field?
|
22
|
+
true
|
23
|
+
end
|
24
|
+
|
12
25
|
def mappings_hash
|
13
26
|
mappings = super
|
14
27
|
if dynamic_templates.any?
|
data/lib/chewy/index/actions.rb
CHANGED
@@ -56,10 +56,16 @@ module Chewy
|
|
56
56
|
options = args.extract_options!.reverse_merge!(alias: true)
|
57
57
|
name = build_index_name(suffix: args.first)
|
58
58
|
|
59
|
-
Chewy.
|
59
|
+
if Chewy::Runtime.version >= 1.1
|
60
|
+
body = index_params
|
61
|
+
body.merge!(aliases: {index_name => {}}) if options[:alias] && name != index_name
|
62
|
+
result = client.indices.create(index: name, body: body)
|
63
|
+
else
|
64
|
+
result = client.indices.create(index: name, body: index_params)
|
65
|
+
result &&= client.indices.put_alias(index: name, name: index_name) if options[:alias] && name != index_name
|
66
|
+
end
|
60
67
|
|
61
|
-
|
62
|
-
result &&= client.indices.put_alias(index: name, name: index_name) if options[:alias] && name != index_name
|
68
|
+
Chewy.wait_for_status if result
|
63
69
|
result
|
64
70
|
end
|
65
71
|
|
@@ -87,9 +93,9 @@ module Chewy
|
|
87
93
|
# UsersIndex.delete '01-2014' # deletes `users_01-2014` index
|
88
94
|
#
|
89
95
|
def delete! suffix = nil
|
90
|
-
|
91
|
-
|
92
|
-
|
96
|
+
result = client.indices.delete index: build_index_name(suffix: suffix)
|
97
|
+
Chewy.wait_for_status if result
|
98
|
+
result
|
93
99
|
end
|
94
100
|
|
95
101
|
# Deletes and recreates index. Supports suffixes.
|
@@ -128,6 +134,8 @@ module Chewy
|
|
128
134
|
# UsersIndex.import suffix: Time.now.to_i # imports data to index with specified suffix if such is exists
|
129
135
|
# UsersIndex.import batch_size: 300 # import batch size
|
130
136
|
#
|
137
|
+
# See [import.rb](lib/chewy/type/import.rb) for more details.
|
138
|
+
#
|
131
139
|
[:import, :import!].each do |method|
|
132
140
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
133
141
|
def #{method} options = {}
|
data/lib/chewy/index/search.rb
CHANGED
@@ -4,8 +4,9 @@ module Chewy
|
|
4
4
|
extend ActiveSupport::Concern
|
5
5
|
|
6
6
|
included do
|
7
|
-
singleton_class.delegate :explain, :limit, :offset, :
|
8
|
-
:
|
7
|
+
singleton_class.delegate :explain, :limit, :offset, :highlight, :rescore,
|
8
|
+
:facets, :aggregations, :none, :strategy, :query, :filter, :post_filter,
|
9
|
+
:order, :reorder, :only, :types, :suggest, to: :all
|
9
10
|
end
|
10
11
|
|
11
12
|
module ClassMethods
|
data/lib/chewy/query.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
begin
|
2
|
-
require 'kaminari'
|
3
|
-
rescue LoadError
|
4
|
-
end
|
5
|
-
|
6
1
|
require 'chewy/query/criteria'
|
7
2
|
require 'chewy/query/filters'
|
8
3
|
require 'chewy/query/loading'
|
@@ -21,7 +16,17 @@ module Chewy
|
|
21
16
|
include Loading
|
22
17
|
include Pagination
|
23
18
|
|
24
|
-
|
19
|
+
RESULT_MERGER = lambda do |key, old_value, new_value|
|
20
|
+
if old_value.is_a?(Hash) && new_value.is_a?(Hash)
|
21
|
+
old_value.merge(new_value, &RESULT_MERGER)
|
22
|
+
elsif new_value.is_a?(Array) && new_value.count > 1
|
23
|
+
new_value
|
24
|
+
else
|
25
|
+
old_value.is_a?(Array) ? new_value : new_value.first
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
delegate :each, :count, :size, to: :_collection
|
25
30
|
alias_method :to_ary, :to_a
|
26
31
|
|
27
32
|
attr_reader :index, :options, :criteria
|
@@ -62,7 +67,7 @@ module Chewy
|
|
62
67
|
# UsersIndex::User.filter(term: {name: 'Johny'}).explain.first._explanation # => {...}
|
63
68
|
#
|
64
69
|
def explain value = nil
|
65
|
-
chain { criteria.
|
70
|
+
chain { criteria.update_request_options explain: (value.nil? ? true : value) }
|
66
71
|
end
|
67
72
|
|
68
73
|
# Sets query compilation mode for search request.
|
@@ -207,6 +212,18 @@ module Chewy
|
|
207
212
|
chain { criteria.update_options filter_mode: value }
|
208
213
|
end
|
209
214
|
|
215
|
+
# Acts the same way as `filter_mode`, but used for `post_filter`.
|
216
|
+
# Note that it fallbacks by default to `Chewy.filter_mode` if
|
217
|
+
# `Chewy.post_filter_mode` is nil.
|
218
|
+
#
|
219
|
+
# UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode(:and)
|
220
|
+
# UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode(:should)
|
221
|
+
# UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }.post_filter_mode('50%')
|
222
|
+
#
|
223
|
+
def post_filter_mode value
|
224
|
+
chain { criteria.update_options post_filter_mode: value }
|
225
|
+
end
|
226
|
+
|
210
227
|
# Sets elasticsearch <tt>size</tt> search request param
|
211
228
|
# Default value is set in the elasticsearch and is 10.
|
212
229
|
#
|
@@ -217,7 +234,7 @@ module Chewy
|
|
217
234
|
# }}
|
218
235
|
#
|
219
236
|
def limit value
|
220
|
-
chain { criteria.
|
237
|
+
chain { criteria.update_request_options size: Integer(value) }
|
221
238
|
end
|
222
239
|
|
223
240
|
# Sets elasticsearch <tt>from</tt> search request param
|
@@ -229,7 +246,23 @@ module Chewy
|
|
229
246
|
# }}
|
230
247
|
#
|
231
248
|
def offset value
|
232
|
-
chain { criteria.
|
249
|
+
chain { criteria.update_request_options from: Integer(value) }
|
250
|
+
end
|
251
|
+
|
252
|
+
# Elasticsearch highlight query option support
|
253
|
+
#
|
254
|
+
# UsersIndex.query(...).highlight(fields: { ... })
|
255
|
+
#
|
256
|
+
def highlight value
|
257
|
+
chain { criteria.update_request_options highlight: value }
|
258
|
+
end
|
259
|
+
|
260
|
+
# Elasticsearch rescore query option support
|
261
|
+
#
|
262
|
+
# UsersIndex.query(...).rescore(query: { ... })
|
263
|
+
#
|
264
|
+
def rescore value
|
265
|
+
chain { criteria.update_request_options rescore: value }
|
233
266
|
end
|
234
267
|
|
235
268
|
# Adds facets section to the search request.
|
@@ -274,6 +307,27 @@ module Chewy
|
|
274
307
|
end
|
275
308
|
alias :aggs :aggregations
|
276
309
|
|
310
|
+
# Sets elasticsearch <tt>suggest</tt> search request param
|
311
|
+
#
|
312
|
+
# UsersIndex.suggest(name: {text: 'Joh', term: {field: 'name'}})
|
313
|
+
# # => {body: {
|
314
|
+
# query: {...},
|
315
|
+
# suggest: {
|
316
|
+
# text: 'Joh',
|
317
|
+
# term: {
|
318
|
+
# field: 'name'
|
319
|
+
# }
|
320
|
+
# }
|
321
|
+
# }}
|
322
|
+
#
|
323
|
+
def suggest params = nil
|
324
|
+
if params
|
325
|
+
chain { criteria.update_suggest params }
|
326
|
+
else
|
327
|
+
_response['suggest'] || {}
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
277
331
|
# Marks the criteria as having zero records. This scope always returns empty array
|
278
332
|
# without touching the elasticsearch server.
|
279
333
|
# All the chained calls of methods don't affect the result
|
@@ -288,6 +342,20 @@ module Chewy
|
|
288
342
|
chain { criteria.update_options none: true }
|
289
343
|
end
|
290
344
|
|
345
|
+
# Setups strategy for top-level filtered query
|
346
|
+
#
|
347
|
+
# UsersIndex.filter { name == 'Johny'}.strategy(:leap_frog)
|
348
|
+
# # => {body: {
|
349
|
+
# query: { filtered: {
|
350
|
+
# filter: { term: { name: 'Johny' } },
|
351
|
+
# strategy: 'leap_frog'
|
352
|
+
# } }
|
353
|
+
# }}
|
354
|
+
#
|
355
|
+
def strategy value = nil
|
356
|
+
chain { criteria.update_options strategy: value }
|
357
|
+
end
|
358
|
+
|
291
359
|
# Adds one or more query to the search request
|
292
360
|
# Internally queries are stored as an array
|
293
361
|
# While the full query compilation this array compiles
|
@@ -319,7 +387,7 @@ module Chewy
|
|
319
387
|
# While the full query compilation this array compiles
|
320
388
|
# according to <tt>:filter_mode</tt> option value
|
321
389
|
#
|
322
|
-
# By default it
|
390
|
+
# By default it joins inside <tt>and</tt> filter
|
323
391
|
# See <tt>#filter_mode</tt> chainable method for more info.
|
324
392
|
#
|
325
393
|
# Also this method supports block DSL.
|
@@ -347,6 +415,37 @@ module Chewy
|
|
347
415
|
chain { criteria.update_filters params }
|
348
416
|
end
|
349
417
|
|
418
|
+
# Adds one or more post_filter to the search request
|
419
|
+
# Internally post_filters are stored as an array
|
420
|
+
# While the full query compilation this array compiles
|
421
|
+
# according to <tt>:post_filter_mode</tt> option value
|
422
|
+
#
|
423
|
+
# By default it joins inside <tt>and</tt> filter
|
424
|
+
# See <tt>#post_filter_mode</tt> chainable method for more info.
|
425
|
+
#
|
426
|
+
# Also this method supports block DSL.
|
427
|
+
# See <tt>Chewy::Query::Filters</tt> for more info.
|
428
|
+
#
|
429
|
+
# UsersIndex.post_filter(term: {name: 'Johny'}).post_filter(range: {age: {lte: 42}})
|
430
|
+
# UsersIndex::User.post_filter(term: {name: 'Johny'}).post_filter(range: {age: {lte: 42}})
|
431
|
+
# UsersIndex.post_filter{ name == 'Johny' }.post_filter{ age <= 42 }
|
432
|
+
# # => {body: {
|
433
|
+
# post_filter: {and: [{term: {name: 'Johny'}}, {range: {age: {lte: 42}}}]}
|
434
|
+
# }}
|
435
|
+
#
|
436
|
+
# If only one post_filter was specified, it will become a result
|
437
|
+
# post_filter as is, without joining.
|
438
|
+
#
|
439
|
+
# UsersIndex.post_filter(term: {name: 'Johny'})
|
440
|
+
# # => {body: {
|
441
|
+
# post_filter: {term: {name: 'Johny'}}
|
442
|
+
# }}
|
443
|
+
#
|
444
|
+
def post_filter params = nil, &block
|
445
|
+
params = Filters.new(&block).__render__ if block
|
446
|
+
chain { criteria.update_post_filters params }
|
447
|
+
end
|
448
|
+
|
350
449
|
# Sets search request sorting
|
351
450
|
#
|
352
451
|
# UsersIndex.order(:first_name, :last_name).order(age: :desc).order(price: {order: :asc, mode: :avg})
|
@@ -474,7 +573,7 @@ module Chewy
|
|
474
573
|
end
|
475
574
|
|
476
575
|
def reset
|
477
|
-
@_request, @_response, @_results = nil
|
576
|
+
@_request, @_response, @_results, @_collection = nil
|
478
577
|
end
|
479
578
|
|
480
579
|
def _request
|
@@ -484,17 +583,32 @@ module Chewy
|
|
484
583
|
def _response
|
485
584
|
@_response ||= begin
|
486
585
|
ActiveSupport::Notifications.instrument 'search_query.chewy', request: _request, index: index do
|
487
|
-
|
586
|
+
begin
|
587
|
+
index.client.search(_request)
|
588
|
+
rescue Elasticsearch::Transport::Transport::Errors::NotFound => e
|
589
|
+
raise e if e.message !~ /IndexMissingException/
|
590
|
+
{}
|
591
|
+
end
|
488
592
|
end
|
489
593
|
end
|
490
594
|
end
|
491
595
|
|
492
596
|
def _results
|
493
|
-
@_results ||= (criteria.none? ? [] : _response['hits']['hits']).map do |hit|
|
494
|
-
attributes = hit['_source'] || {}
|
495
|
-
attributes.reverse_merge!(id: hit['_id'])
|
496
|
-
|
497
|
-
index.type_hash[hit['_type']].new attributes
|
597
|
+
@_results ||= (criteria.none? || _response == {} ? [] : _response['hits']['hits']).map do |hit|
|
598
|
+
attributes = (hit['_source'] || {}).merge(hit['highlight'] || {}, &RESULT_MERGER)
|
599
|
+
attributes.reverse_merge!(id: hit['_id']).merge!(_score: hit['_score'])
|
600
|
+
|
601
|
+
wrapper = index.type_hash[hit['_type']].new attributes
|
602
|
+
wrapper._data = hit
|
603
|
+
wrapper
|
604
|
+
end
|
605
|
+
end
|
606
|
+
|
607
|
+
def _collection
|
608
|
+
@_collection ||= begin
|
609
|
+
_load_objects! if criteria.options[:preload]
|
610
|
+
criteria.options[:preload] && criteria.options[:loaded_objects] ?
|
611
|
+
_results.map(&:_object) : _results
|
498
612
|
end
|
499
613
|
end
|
500
614
|
end
|
data/lib/chewy/query/compose.rb
CHANGED
@@ -4,16 +4,26 @@ module Chewy
|
|
4
4
|
|
5
5
|
protected
|
6
6
|
|
7
|
-
def
|
8
|
-
if
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
7
|
+
def _filtered_query query, filter, options = {}
|
8
|
+
query = { match_all: {} } if !query.present? && filter.present?
|
9
|
+
|
10
|
+
if filter.present?
|
11
|
+
filtered = if query.present?
|
12
|
+
{ query: { filtered: {
|
13
|
+
query: query,
|
14
|
+
filter: filter
|
15
|
+
} } }
|
16
|
+
else
|
17
|
+
{ query: { filtered: {
|
18
|
+
filter: filter
|
19
|
+
} } }
|
20
|
+
end
|
21
|
+
filtered[:query][:filtered].merge!(strategy: options[:strategy].to_s) if options[:strategy].present?
|
22
|
+
filtered
|
23
|
+
elsif query.present?
|
24
|
+
{ query: query }
|
25
|
+
else
|
26
|
+
{ }
|
17
27
|
end
|
18
28
|
end
|
19
29
|
|
@@ -23,14 +33,14 @@ module Chewy
|
|
23
33
|
if queries.many?
|
24
34
|
case logic
|
25
35
|
when :dis_max
|
26
|
-
{dis_max: {queries: queries}}
|
36
|
+
{ dis_max: { queries: queries } }
|
27
37
|
when :must, :should
|
28
|
-
{bool: {logic => queries}}
|
38
|
+
{ bool: { logic => queries } }
|
29
39
|
else
|
30
40
|
if logic.is_a?(Float)
|
31
|
-
{dis_max: {queries: queries, tie_breaker: logic}}
|
41
|
+
{ dis_max: { queries: queries, tie_breaker: logic } }
|
32
42
|
else
|
33
|
-
{bool: {should: queries, minimum_should_match: logic}}
|
43
|
+
{ bool: { should: queries, minimum_should_match: logic } }
|
34
44
|
end
|
35
45
|
end
|
36
46
|
else
|
@@ -44,11 +54,11 @@ module Chewy
|
|
44
54
|
if filters.many?
|
45
55
|
case logic
|
46
56
|
when :and, :or
|
47
|
-
{logic => filters}
|
57
|
+
{ logic => filters }
|
48
58
|
when :must, :should
|
49
|
-
{bool: {logic => filters}}
|
59
|
+
{ bool: { logic => filters } }
|
50
60
|
else
|
51
|
-
{bool: {should: filters, minimum_should_match: logic}}
|
61
|
+
{ bool: { should: filters, minimum_should_match: logic } }
|
52
62
|
end
|
53
63
|
else
|
54
64
|
filters.first
|
data/lib/chewy/query/criteria.rb
CHANGED
@@ -4,12 +4,16 @@ module Chewy
|
|
4
4
|
class Query
|
5
5
|
class Criteria
|
6
6
|
include Compose
|
7
|
-
ARRAY_STORAGES = [:queries, :filters, :sort, :fields, :types]
|
8
|
-
HASH_STORAGES = [:options, :facets, :aggregations]
|
7
|
+
ARRAY_STORAGES = [:queries, :filters, :post_filters, :sort, :fields, :types]
|
8
|
+
HASH_STORAGES = [:options, :request_options, :facets, :aggregations, :suggest]
|
9
9
|
STORAGES = ARRAY_STORAGES + HASH_STORAGES
|
10
10
|
|
11
11
|
def initialize options = {}
|
12
|
-
@options = options.merge(
|
12
|
+
@options = options.merge(
|
13
|
+
query_mode: Chewy.query_mode,
|
14
|
+
filter_mode: Chewy.filter_mode,
|
15
|
+
post_filter_mode: Chewy.filter_mode || Chewy.post_filter_mode
|
16
|
+
)
|
13
17
|
end
|
14
18
|
|
15
19
|
def == other
|
@@ -40,6 +44,10 @@ module Chewy
|
|
40
44
|
options.merge!(modifer)
|
41
45
|
end
|
42
46
|
|
47
|
+
def update_request_options(modifer)
|
48
|
+
request_options.merge!(modifer)
|
49
|
+
end
|
50
|
+
|
43
51
|
def update_facets(modifer)
|
44
52
|
facets.merge!(modifer)
|
45
53
|
end
|
@@ -48,12 +56,16 @@ module Chewy
|
|
48
56
|
aggregations.merge!(modifer)
|
49
57
|
end
|
50
58
|
|
51
|
-
def
|
52
|
-
|
59
|
+
def update_suggest(modifier)
|
60
|
+
suggest.merge!(modifier)
|
53
61
|
end
|
54
62
|
|
55
|
-
|
56
|
-
|
63
|
+
[:filters, :queries, :post_filters].each do |storage|
|
64
|
+
class_eval <<-RUBY
|
65
|
+
def update_#{storage}(modifer)
|
66
|
+
@#{storage} = #{storage} + Array.wrap(modifer).reject(&:blank?)
|
67
|
+
end
|
68
|
+
RUBY
|
57
69
|
end
|
58
70
|
|
59
71
|
def update_sort(modifer, options = {})
|
@@ -85,14 +97,17 @@ module Chewy
|
|
85
97
|
end
|
86
98
|
|
87
99
|
def request_body
|
88
|
-
body =
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
100
|
+
body = {}
|
101
|
+
|
102
|
+
body.merge!(_filtered_query(_request_query, _request_filter, options.slice(:strategy)))
|
103
|
+
body.merge!(post_filter: _request_post_filter) if post_filters?
|
104
|
+
body.merge!(facets: facets) if facets?
|
105
|
+
body.merge!(aggregations: aggregations) if aggregations?
|
106
|
+
body.merge!(suggest: suggest) if suggest?
|
107
|
+
body.merge!(sort: sort) if sort?
|
108
|
+
body.merge!(_source: fields) if fields?
|
94
109
|
|
95
|
-
{body: body.merge!(
|
110
|
+
{ body: body.merge!(request_options) }
|
96
111
|
end
|
97
112
|
|
98
113
|
protected
|
@@ -104,17 +119,10 @@ module Chewy
|
|
104
119
|
def initialize_clone(other)
|
105
120
|
STORAGES.each do |storage|
|
106
121
|
value = other.send(storage)
|
107
|
-
|
108
|
-
value = Marshal.load(Marshal.dump(value))
|
109
|
-
instance_variable_set("@#{storage}", value)
|
110
|
-
end
|
122
|
+
instance_variable_set("@#{storage}", value.deep_dup)
|
111
123
|
end
|
112
124
|
end
|
113
125
|
|
114
|
-
def _request_options
|
115
|
-
options.slice(:size, :from, :explain, :aggregations)
|
116
|
-
end
|
117
|
-
|
118
126
|
def _request_query
|
119
127
|
_queries_join(queries, options[:query_mode])
|
120
128
|
end
|
@@ -133,6 +141,10 @@ module Chewy
|
|
133
141
|
def _request_types
|
134
142
|
_filters_join(types.map { |type| {type: {value: type}} }, :or)
|
135
143
|
end
|
144
|
+
|
145
|
+
def _request_post_filter
|
146
|
+
_filters_join(post_filters, options[:post_filter_mode])
|
147
|
+
end
|
136
148
|
end
|
137
149
|
end
|
138
150
|
end
|