chewy 5.0.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +214 -0
- data/Appraisals +1 -17
- data/CHANGELOG.md +40 -0
- data/Gemfile +2 -0
- data/LICENSE.txt +1 -1
- data/README.md +61 -35
- data/chewy.gemspec +4 -4
- data/gemfiles/rails.5.2.activerecord.gemfile +4 -3
- data/gemfiles/{rails.5.0.activerecord.gemfile → rails.5.2.mongoid.6.4.gemfile} +4 -3
- data/gemfiles/{rails.5.0.mongoid.6.1.gemfile → rails.6.0.activerecord.gemfile} +4 -3
- data/gemfiles/{rails.5.1.activerecord.gemfile → rails.6.1.activerecord.gemfile} +6 -3
- data/gemfiles/ruby3.gemfile +10 -0
- data/lib/chewy/backports/duplicable.rb +1 -1
- data/lib/chewy/fields/base.rb +1 -1
- data/lib/chewy/fields/root.rb +2 -2
- data/lib/chewy/index/actions.rb +9 -3
- data/lib/chewy/query/loading.rb +1 -1
- data/lib/chewy/query/nodes/field.rb +1 -1
- data/lib/chewy/query.rb +5 -0
- data/lib/chewy/railtie.rb +1 -1
- data/lib/chewy/search/loader.rb +1 -1
- data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
- data/lib/chewy/search/parameters/indices.rb +123 -0
- data/lib/chewy/search/parameters.rb +24 -6
- data/lib/chewy/search/request.rb +76 -51
- data/lib/chewy/search/scrolling.rb +3 -5
- data/lib/chewy/search.rb +1 -5
- data/lib/chewy/strategy/active_job.rb +1 -1
- data/lib/chewy/strategy/sidekiq.rb +1 -1
- data/lib/chewy/type/adapter/active_record.rb +1 -1
- data/lib/chewy/type/adapter/mongoid.rb +1 -1
- data/lib/chewy/type/adapter/orm.rb +1 -1
- data/lib/chewy/type/adapter/sequel.rb +1 -1
- data/lib/chewy/type/import/bulk_request.rb +4 -2
- data/lib/chewy/type/import/journal_builder.rb +1 -1
- data/lib/chewy/type/import/routine.rb +1 -1
- data/lib/chewy/type/import.rb +3 -3
- data/lib/chewy/type/mapping.rb +4 -4
- data/lib/chewy/type/observe.rb +3 -3
- data/lib/chewy/type/witchcraft.rb +1 -1
- data/lib/chewy/type/wrapper.rb +1 -1
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +1 -1
- data/spec/chewy/config_spec.rb +1 -1
- data/spec/chewy/fields/base_spec.rb +11 -9
- data/spec/chewy/index/actions_spec.rb +2 -2
- data/spec/chewy/journal_spec.rb +1 -1
- data/spec/chewy/search/parameters/indices_spec.rb +191 -0
- data/spec/chewy/search/parameters_spec.rb +20 -3
- data/spec/chewy/search/request_spec.rb +25 -9
- data/spec/chewy/search/response_spec.rb +8 -2
- data/spec/chewy/search_spec.rb +2 -2
- data/spec/chewy/strategy/active_job_spec.rb +15 -2
- data/spec/chewy/strategy/shoryuken_spec.rb +6 -2
- data/spec/chewy/strategy/sidekiq_spec.rb +6 -2
- data/spec/chewy/type/adapter/active_record_spec.rb +3 -3
- data/spec/chewy/type/import/bulk_builder_spec.rb +1 -1
- data/spec/chewy/type/observe_spec.rb +4 -4
- data/spec/spec_helper.rb +4 -1
- metadata +21 -22
- data/.travis.yml +0 -45
- data/gemfiles/rails.4.0.activerecord.gemfile +0 -15
- data/gemfiles/rails.4.1.activerecord.gemfile +0 -15
- data/gemfiles/rails.4.2.activerecord.gemfile +0 -16
- data/gemfiles/rails.4.2.mongoid.5.2.gemfile +0 -16
- data/gemfiles/rails.5.1.mongoid.6.3.gemfile +0 -16
- data/spec/chewy/search/parameters/indices_boost_spec.rb +0 -83
data/lib/chewy/index/actions.rb
CHANGED
@@ -30,8 +30,8 @@ module Chewy
|
|
30
30
|
# Suffixed index names might be used for zero-downtime mapping change, for example.
|
31
31
|
# Description: (http://www.elasticsearch.org/blog/changing-mapping-with-zero-downtime/).
|
32
32
|
#
|
33
|
-
def create(*args)
|
34
|
-
create!(*args)
|
33
|
+
def create(*args, **kwargs)
|
34
|
+
create!(*args, **kwargs)
|
35
35
|
rescue Elasticsearch::Transport::Transport::Errors::BadRequest
|
36
36
|
false
|
37
37
|
end
|
@@ -74,7 +74,13 @@ module Chewy
|
|
74
74
|
# UsersIndex.delete '01-2014' # deletes `users_01-2014` index
|
75
75
|
#
|
76
76
|
def delete(suffix = nil)
|
77
|
-
|
77
|
+
# Verify that the index_name is really the index_name and not an alias.
|
78
|
+
#
|
79
|
+
# "The index parameter in the delete index API no longer accepts alias names.
|
80
|
+
# Instead, it accepts only index names (or wildcards which will expand to matching indices)."
|
81
|
+
# https://www.elastic.co/guide/en/elasticsearch/reference/6.8/breaking-changes-6.0.html#_delete_index_api_resolves_indices_expressions_only_against_indices
|
82
|
+
index_names = client.indices.get_alias(index: index_name(suffix: suffix)).keys
|
83
|
+
result = client.indices.delete index: index_names.join(',')
|
78
84
|
Chewy.wait_for_status if result
|
79
85
|
result
|
80
86
|
# es-ruby >= 1.0.10 handles Elasticsearch::Transport::Transport::Errors::NotFound
|
data/lib/chewy/query/loading.rb
CHANGED
@@ -94,7 +94,7 @@ module Chewy
|
|
94
94
|
loaded_objects = Hash[_results.group_by(&:class).map do |type, objects|
|
95
95
|
next if except.include?(type.type_name)
|
96
96
|
next if only.present? && !only.include?(type.type_name)
|
97
|
-
loaded = type.adapter.load(objects.map(&:id), options.merge(_type: type)) || objects
|
97
|
+
loaded = type.adapter.load(objects.map(&:id), **options.merge(_type: type)) || objects
|
98
98
|
[type, loaded.index_by.with_index do |loaded_object, i|
|
99
99
|
objects[i]._object = loaded_object
|
100
100
|
objects[i]
|
@@ -39,7 +39,7 @@ module Chewy
|
|
39
39
|
when ::Regexp
|
40
40
|
Nodes::Regexp.new @name, other, *@args
|
41
41
|
when ::Range
|
42
|
-
Nodes::Range.new @name, *__options_merge__(gt: other.
|
42
|
+
Nodes::Range.new @name, *__options_merge__(gt: other.begin, lt: other.end)
|
43
43
|
else
|
44
44
|
if other.is_a?(Array) && other.first.is_a?(::Range)
|
45
45
|
Nodes::Range.new @name, *__options_merge__(
|
data/lib/chewy/query.rb
CHANGED
@@ -40,6 +40,11 @@ module Chewy
|
|
40
40
|
@criteria = Criteria.new
|
41
41
|
end
|
42
42
|
|
43
|
+
# A compatibility layer with the new request DSL.
|
44
|
+
def render
|
45
|
+
_request
|
46
|
+
end
|
47
|
+
|
43
48
|
# Comparation with other query or collection
|
44
49
|
# If other is collection - search request is executed and
|
45
50
|
# result is used for comparation
|
data/lib/chewy/railtie.rb
CHANGED
@@ -68,7 +68,7 @@ module Chewy
|
|
68
68
|
end
|
69
69
|
|
70
70
|
initializer 'chewy.request_strategy' do |app|
|
71
|
-
app.config.middleware.
|
71
|
+
app.config.middleware.insert_before(ActionDispatch::ShowExceptions, RequestStrategy)
|
72
72
|
end
|
73
73
|
|
74
74
|
initializer 'chewy.add_indices_path' do |_app|
|
data/lib/chewy/search/loader.rb
CHANGED
@@ -52,7 +52,7 @@ module Chewy
|
|
52
52
|
|
53
53
|
type = derive_type(index_name, type_name)
|
54
54
|
ids = hit_group.map { |hit| hit['_id'] }
|
55
|
-
loaded = type.adapter.load(ids,
|
55
|
+
loaded = type.adapter.load(ids, **@options.merge(_type: type))
|
56
56
|
loaded ||= hit_group.map { |hit| type.build(hit) }
|
57
57
|
|
58
58
|
result.merge!(hit_group.zip(loaded).to_h)
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'chewy/search/parameters/storage'
|
2
|
+
|
3
|
+
module Chewy
|
4
|
+
module Search
|
5
|
+
class Parameters
|
6
|
+
# Stores boolean value, but has 3 states: `true`, `false` and `nil`.
|
7
|
+
#
|
8
|
+
# @see Chewy::Search::Request#allow_partial_search_results
|
9
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/6.4/search-request-body.html#_parameters_4
|
10
|
+
class AllowPartialSearchResults < Storage
|
11
|
+
# We don't want to render `nil`, but render `true` and `false` values.
|
12
|
+
#
|
13
|
+
# @see Chewy::Search::Parameters::Storage#render
|
14
|
+
# @return [{Symbol => Object}, nil]
|
15
|
+
def render
|
16
|
+
{self.class.param_name => value} unless value.nil?
|
17
|
+
end
|
18
|
+
|
19
|
+
private
|
20
|
+
|
21
|
+
def normalize(value)
|
22
|
+
!!value unless value.nil?
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require 'chewy/search/parameters/storage'
|
2
|
+
|
3
|
+
module Chewy
|
4
|
+
module Search
|
5
|
+
class Parameters
|
6
|
+
# Stores indices and/or types to query.
|
7
|
+
# Renders it to lists of string accepted by ElasticSearch
|
8
|
+
# API.
|
9
|
+
#
|
10
|
+
# The semantics behind it can be described in the
|
11
|
+
# following statements:
|
12
|
+
# 1. If index is added to the storage, no matter, a class
|
13
|
+
# or a string/symbol, it gets appended to the list.
|
14
|
+
# 2. If type is added to the storage, it filters out types
|
15
|
+
# assigned via indices.
|
16
|
+
# 3. But when a type class with non-existing index is added,
|
17
|
+
# this index got also added to the list if indices.
|
18
|
+
# 4. In cases when of an index identifier added, type
|
19
|
+
# indetifiers also got appended instead of filtering.
|
20
|
+
class Indices < Storage
|
21
|
+
# Two index storages are equal if they produce the
|
22
|
+
# same output on render.
|
23
|
+
#
|
24
|
+
# @see Chewy::Search::Parameters::Storage#==
|
25
|
+
# @param other [Chewy::Search::Parameters::Storage] any storage instance
|
26
|
+
# @return [true, false] the result of comparision
|
27
|
+
def ==(other)
|
28
|
+
super || other.class == self.class && other.render == render
|
29
|
+
end
|
30
|
+
|
31
|
+
# Just adds types to types and indices to indices.
|
32
|
+
#
|
33
|
+
# @see Chewy::Search::Parameters::Storage#update!
|
34
|
+
# @param other_value [{Symbol => Array<Chewy::Index, Chewy::Type, String, Symbol>}] any acceptable storage value
|
35
|
+
# @return [{Symbol => Array<Chewy::Index, Chewy::Type, String, Symbol>}] updated value
|
36
|
+
def update!(other_value)
|
37
|
+
new_value = normalize(other_value)
|
38
|
+
|
39
|
+
@value = {
|
40
|
+
indices: value[:indices] | new_value[:indices],
|
41
|
+
types: value[:types] | new_value[:types]
|
42
|
+
}
|
43
|
+
end
|
44
|
+
|
45
|
+
# Returns desired index and type names.
|
46
|
+
#
|
47
|
+
# @see Chewy::Search::Parameters::Storage#render
|
48
|
+
# @return [{Symbol => Array<String>}] rendered value with the parameter name
|
49
|
+
def render
|
50
|
+
{
|
51
|
+
index: index_names.uniq.sort,
|
52
|
+
type: type_names.uniq.sort
|
53
|
+
}.reject { |_, v| v.blank? }
|
54
|
+
end
|
55
|
+
|
56
|
+
# Returns index classes used for the request.
|
57
|
+
# No strings/symbos included.
|
58
|
+
#
|
59
|
+
# @return [Array<Chewy::Index>] a list of index classes
|
60
|
+
def indices
|
61
|
+
index_classes | type_classes.map(&:index)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Returns type classes used for the request.
|
65
|
+
# No strings/symbos included.
|
66
|
+
#
|
67
|
+
# @return [Array<Chewy::Type>] a list of types classes
|
68
|
+
def types
|
69
|
+
type_classes | (index_classes - type_classes.map(&:index)).flat_map(&:types)
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def initialize_clone(origin)
|
75
|
+
@value = origin.value.dup
|
76
|
+
end
|
77
|
+
|
78
|
+
def normalize(value)
|
79
|
+
value ||= {}
|
80
|
+
|
81
|
+
{
|
82
|
+
indices: Array.wrap(value[:indices]).flatten.compact,
|
83
|
+
types: Array.wrap(value[:types]).flatten.compact
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def index_classes
|
88
|
+
value[:indices].select do |klass|
|
89
|
+
klass.is_a?(Class) && klass < Chewy::Index
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
def index_identifiers
|
94
|
+
value[:indices] - index_classes
|
95
|
+
end
|
96
|
+
|
97
|
+
def index_names
|
98
|
+
indices.map(&:index_name) | index_identifiers.map(&:to_s)
|
99
|
+
end
|
100
|
+
|
101
|
+
def type_classes
|
102
|
+
value[:types].select do |klass|
|
103
|
+
klass.is_a?(Class) && klass < Chewy::Type
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
def type_identifiers
|
108
|
+
value[:types] - type_classes
|
109
|
+
end
|
110
|
+
|
111
|
+
def type_names
|
112
|
+
type_names = types.map(&:type_name)
|
113
|
+
|
114
|
+
if index_identifiers.blank? && type_identifiers.present?
|
115
|
+
(type_names & type_identifiers.map(&:to_s)).presence || type_names
|
116
|
+
else
|
117
|
+
type_names | type_identifiers.map(&:to_s)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -10,6 +10,8 @@ module Chewy
|
|
10
10
|
# @see Chewy::Search::Request#parameters
|
11
11
|
# @see Chewy::Search::Parameters::Storage
|
12
12
|
class Parameters
|
13
|
+
QUERY_STRING_STORAGES = %i[indices search_type request_cache allow_partial_search_results].freeze
|
14
|
+
|
13
15
|
# Default storage classes warehouse. It is probably possible to
|
14
16
|
# add your own classes here if necessary, but I'm not sure it will work.
|
15
17
|
#
|
@@ -33,10 +35,11 @@ module Chewy
|
|
33
35
|
# limit: Chewy::Search::Parameters::Offset.new(10)
|
34
36
|
# )
|
35
37
|
# @param initial [{Symbol => Object, Chewy::Search::Parameters::Storage}]
|
36
|
-
def initialize(initial = {})
|
38
|
+
def initialize(initial = {}, **kinitial)
|
37
39
|
@storages = Hash.new do |hash, name|
|
38
40
|
hash[name] = self.class.storages[name].new
|
39
41
|
end
|
42
|
+
initial = initial.deep_dup.merge(kinitial)
|
40
43
|
initial.each_with_object(@storages) do |(name, value), result|
|
41
44
|
storage_class = self.class.storages[name]
|
42
45
|
storage = value.is_a?(storage_class) ? value : storage_class.new(value)
|
@@ -101,11 +104,7 @@ module Chewy
|
|
101
104
|
#
|
102
105
|
# @return [Hash] request body
|
103
106
|
def render
|
104
|
-
|
105
|
-
result.merge!(storage.render || {})
|
106
|
-
end
|
107
|
-
body.merge!(render_query || {})
|
108
|
-
body.present? ? {body: body} : {}
|
107
|
+
render_query_string_params.merge(render_body)
|
109
108
|
end
|
110
109
|
|
111
110
|
protected
|
@@ -126,6 +125,25 @@ module Chewy
|
|
126
125
|
names
|
127
126
|
end
|
128
127
|
|
128
|
+
def render_query_string_params
|
129
|
+
query_string_storages = @storages.select do |storage_name, _|
|
130
|
+
QUERY_STRING_STORAGES.include?(storage_name)
|
131
|
+
end
|
132
|
+
|
133
|
+
query_string_storages.values.inject({}) do |result, storage|
|
134
|
+
result.merge!(storage.render || {})
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def render_body
|
139
|
+
exceptions = %i[filter query none] + QUERY_STRING_STORAGES
|
140
|
+
body = @storages.except(*exceptions).values.inject({}) do |result, storage|
|
141
|
+
result.merge!(storage.render || {})
|
142
|
+
end
|
143
|
+
body.merge!(render_query || {})
|
144
|
+
{body: body}
|
145
|
+
end
|
146
|
+
|
129
147
|
def render_query
|
130
148
|
none = @storages[:none].render
|
131
149
|
|
data/lib/chewy/search/request.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
module Chewy
|
2
2
|
module Search
|
3
|
-
# The main
|
3
|
+
# The main request DSL class. Supports multiple index requests.
|
4
4
|
# Supports ES2 and ES5 search API and query DSL.
|
5
5
|
#
|
6
6
|
# @note The class tries to be as immutable as possible,
|
@@ -26,8 +26,9 @@ module Chewy
|
|
26
26
|
timeout min_score source stored_fields search_after
|
27
27
|
load script_fields suggest aggs aggregations none
|
28
28
|
indices_boost rescore highlight total total_count
|
29
|
-
total_entries types delete_all count exists?
|
30
|
-
scroll_batches scroll_hits
|
29
|
+
total_entries indices types delete_all count exists?
|
30
|
+
exist? find pluck scroll_batches scroll_hits
|
31
|
+
scroll_results scroll_wrappers
|
31
32
|
].to_set.freeze
|
32
33
|
DEFAULT_BATCH_SIZE = 1000
|
33
34
|
DEFAULT_PLUCK_BATCH_SIZE = 10_000
|
@@ -51,24 +52,32 @@ module Chewy
|
|
51
52
|
alias_method :total_count, :total
|
52
53
|
alias_method :total_entries, :total
|
53
54
|
|
54
|
-
attr_reader :_indexes, :_types
|
55
|
-
|
56
55
|
# The class is initialized with the list of chewy indexes and/or
|
57
56
|
# types, which are later used to compose requests.
|
57
|
+
# Any symbol/string passed is treated as an index identifier.
|
58
58
|
#
|
59
59
|
# @example
|
60
|
+
# Chewy::Search::Request.new(:places)
|
61
|
+
# # => <Chewy::Search::Request {:index=>["places"]}>
|
60
62
|
# Chewy::Search::Request.new(PlacesIndex)
|
61
63
|
# # => <Chewy::Search::Request {:index=>["places"], :type=>["city", "country"]}>
|
62
64
|
# Chewy::Search::Request.new(PlacesIndex::City)
|
63
65
|
# # => <Chewy::Search::Request {:index=>["places"], :type=>["city"]}>
|
64
66
|
# Chewy::Search::Request.new(UsersIndex, PlacesIndex::City)
|
65
67
|
# # => <Chewy::Search::Request {:index=>["users", "places"], :type=>["city", "user"]}>
|
66
|
-
# @param indexes_or_types [Array<Chewy::Index, Chewy::Type>]
|
67
|
-
def initialize(*
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
68
|
+
# @param indexes_or_types [Array<Chewy::Index, Chewy::Type, String, Symbol>] indices and types in any combinations
|
69
|
+
def initialize(*indices_or_types)
|
70
|
+
indices = indices_or_types.reject do |klass|
|
71
|
+
klass.is_a?(Class) && klass < Chewy::Type
|
72
|
+
end
|
73
|
+
|
74
|
+
types = indices_or_types.select do |klass|
|
75
|
+
klass.is_a?(Class) && klass < Chewy::Type
|
76
|
+
end
|
77
|
+
|
78
|
+
parameters.modify!(:indices) do
|
79
|
+
replace!(indices: indices, types: types)
|
80
|
+
end
|
72
81
|
end
|
73
82
|
|
74
83
|
# Underlying parameter storage collection.
|
@@ -110,7 +119,7 @@ module Chewy
|
|
110
119
|
#
|
111
120
|
# @return [Hash] request body
|
112
121
|
def render
|
113
|
-
@render ||=
|
122
|
+
@render ||= parameters.render
|
114
123
|
end
|
115
124
|
|
116
125
|
# Includes the class name and the result of rendering.
|
@@ -281,21 +290,39 @@ module Chewy
|
|
281
290
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-docvalue-fields.html
|
282
291
|
# @param values [Array<String, Symbol>] field names
|
283
292
|
# @return [Chewy::Search::Request]
|
293
|
+
%i[order docvalue_fields].each do |name|
|
294
|
+
define_method name do |value, *values|
|
295
|
+
modify(name) { update!([value, *values]) }
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
# @!method indices(*values)
|
300
|
+
# Modifies `index` request parameter. Updates the storage on every call.
|
301
|
+
# Added passed indexes to the parameter list.
|
302
|
+
#
|
303
|
+
# @example
|
304
|
+
# UsersIndex.indices(CitiesIndex).indices(:another)
|
305
|
+
# # => <UsersIndex::Query {:index=>["another", "cities", "users"], :type=>["city", "user"]}>
|
306
|
+
# @see Chewy::Search::Parameters::Indices
|
307
|
+
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
|
308
|
+
# @param values [Array<Chewy::Index, String, Symbol>] index names
|
309
|
+
# @return [Chewy::Search::Request]
|
284
310
|
#
|
285
311
|
# @!method types(*values)
|
286
|
-
# Modifies `
|
287
|
-
# Constrains types passed on the request initialization
|
312
|
+
# Modifies `type` request parameter. Updates the storage on every call.
|
313
|
+
# Constrains types passed on the request initialization or adds them
|
314
|
+
# to the list depending on circumstances.
|
288
315
|
#
|
289
316
|
# @example
|
290
|
-
#
|
291
|
-
# # => <
|
292
|
-
# @see Chewy::Search::Parameters::
|
317
|
+
# UsersIndex.types(CitiesIndex::City).types(:unexistent)
|
318
|
+
# # => <UsersIndex::Query {:index=>["cities", "users"], :type=>["city", "user"]}>
|
319
|
+
# @see Chewy::Search::Parameters::Indices
|
293
320
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-search.html
|
294
|
-
# @param values [Array<String, Symbol>] type names
|
321
|
+
# @param values [Array<Chewy::Type, String, Symbol>] type names
|
295
322
|
# @return [Chewy::Search::Request]
|
296
|
-
%i[
|
323
|
+
%i[indices types].each do |name|
|
297
324
|
define_method name do |value, *values|
|
298
|
-
modify(
|
325
|
+
modify(:indices) { update!(name => [value, *values]) }
|
299
326
|
end
|
300
327
|
end
|
301
328
|
|
@@ -759,7 +786,7 @@ module Chewy
|
|
759
786
|
# @param values [Array<String, Symbol>]
|
760
787
|
# @return [Chewy::Search::Request] new scope
|
761
788
|
def only(*values)
|
762
|
-
chain { parameters.only!(values.flatten(1)) }
|
789
|
+
chain { parameters.only!(values.flatten(1) + [:indices]) }
|
763
790
|
end
|
764
791
|
|
765
792
|
# Returns a new scope containing all the storages except specified.
|
@@ -912,12 +939,11 @@ module Chewy
|
|
912
939
|
def delete_all(refresh: true)
|
913
940
|
request_body = only(WHERE_STORAGES).render.merge(refresh: refresh)
|
914
941
|
ActiveSupport::Notifications.instrument 'delete_query.chewy',
|
915
|
-
request: request_body
|
916
|
-
index: _indexes.one? ? _indexes.first : _indexes,
|
917
|
-
type: _types.one? ? _types.first : _types do
|
942
|
+
notification_payload(request: request_body) do
|
918
943
|
if Runtime.version < '5.0'
|
919
944
|
delete_by_query_plugin(request_body)
|
920
945
|
else
|
946
|
+
request_body[:body] = {query: {match_all: {}}} if request_body[:body].empty?
|
921
947
|
Chewy.client.delete_by_query(request_body)
|
922
948
|
end
|
923
949
|
end
|
@@ -933,9 +959,7 @@ module Chewy
|
|
933
959
|
private
|
934
960
|
|
935
961
|
def compare_internals(other)
|
936
|
-
|
937
|
-
_types.sort_by(&:derivable_name) == other._types.sort_by(&:derivable_name) &&
|
938
|
-
parameters == other.parameters
|
962
|
+
parameters == other.parameters
|
939
963
|
end
|
940
964
|
|
941
965
|
def modify(name, &block)
|
@@ -947,45 +971,43 @@ module Chewy
|
|
947
971
|
end
|
948
972
|
|
949
973
|
def reset
|
950
|
-
@response, @render, @
|
974
|
+
@response, @render, @loader = nil
|
951
975
|
end
|
952
976
|
|
953
977
|
def perform(additional = {})
|
954
978
|
request_body = render.merge(additional)
|
955
979
|
ActiveSupport::Notifications.instrument 'search_query.chewy',
|
956
|
-
request: request_body
|
957
|
-
|
958
|
-
|
959
|
-
|
960
|
-
|
961
|
-
|
962
|
-
{}
|
980
|
+
notification_payload(request: request_body) do
|
981
|
+
begin
|
982
|
+
Chewy.client.search(request_body)
|
983
|
+
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
984
|
+
{}
|
985
|
+
end
|
963
986
|
end
|
964
|
-
end
|
965
987
|
end
|
966
988
|
|
967
|
-
def
|
968
|
-
|
989
|
+
def notification_payload(additional)
|
990
|
+
{
|
991
|
+
indexes: _indices, types: _types,
|
992
|
+
index: _indices.one? ? _indices.first : _indices,
|
993
|
+
type: _types.one? ? _types.first : _types
|
994
|
+
}.merge(additional)
|
969
995
|
end
|
970
996
|
|
971
|
-
def
|
972
|
-
parameters[:
|
997
|
+
def _indices
|
998
|
+
parameters[:indices].indices
|
973
999
|
end
|
974
1000
|
|
975
|
-
def
|
976
|
-
|
1001
|
+
def _types
|
1002
|
+
parameters[:indices].types
|
977
1003
|
end
|
978
1004
|
|
979
|
-
def
|
980
|
-
|
981
|
-
_types.map(&:type_name).uniq & parameters[:types].value
|
982
|
-
else
|
983
|
-
_types.map(&:type_name).uniq
|
984
|
-
end
|
1005
|
+
def raw_limit_value
|
1006
|
+
parameters[:limit].value
|
985
1007
|
end
|
986
1008
|
|
987
|
-
def
|
988
|
-
|
1009
|
+
def raw_offset_value
|
1010
|
+
parameters[:offset].value
|
989
1011
|
end
|
990
1012
|
|
991
1013
|
def delete_by_query_plugin(request)
|
@@ -998,7 +1020,10 @@ module Chewy
|
|
998
1020
|
end
|
999
1021
|
|
1000
1022
|
def loader
|
1001
|
-
@loader ||= Loader.new(
|
1023
|
+
@loader ||= Loader.new(
|
1024
|
+
indexes: parameters[:indices].indices,
|
1025
|
+
**parameters[:load].value
|
1026
|
+
)
|
1002
1027
|
end
|
1003
1028
|
|
1004
1029
|
def fetch_field(hit, field)
|
@@ -125,11 +125,9 @@ module Chewy
|
|
125
125
|
|
126
126
|
def perform_scroll(body)
|
127
127
|
ActiveSupport::Notifications.instrument 'search_query.chewy',
|
128
|
-
request: body
|
129
|
-
|
130
|
-
|
131
|
-
Chewy.client.scroll(body)
|
132
|
-
end
|
128
|
+
notification_payload(request: body) do
|
129
|
+
Chewy.client.scroll(body)
|
130
|
+
end
|
133
131
|
end
|
134
132
|
end
|
135
133
|
end
|
data/lib/chewy/search.rb
CHANGED
@@ -58,11 +58,7 @@ module Chewy
|
|
58
58
|
# @see https://www.elastic.co/guide/en/elasticsearch/reference/current/search-uri-request.html
|
59
59
|
# @return [Hash] the request result
|
60
60
|
def search_string(query, options = {})
|
61
|
-
options = options.merge(
|
62
|
-
index: all._indexes.map(&:index_name),
|
63
|
-
type: all._types.map(&:type_name),
|
64
|
-
q: query
|
65
|
-
)
|
61
|
+
options = options.merge(all.render.slice(:index, :type).merge(q: query))
|
66
62
|
Chewy.client.search(options)
|
67
63
|
end
|
68
64
|
|
@@ -11,7 +11,7 @@ module Chewy
|
|
11
11
|
#
|
12
12
|
class ActiveJob < Atomic
|
13
13
|
class Worker < ::ActiveJob::Base
|
14
|
-
queue_as :chewy
|
14
|
+
queue_as { Chewy.settings.dig(:active_job, :queue) || 'chewy' }
|
15
15
|
|
16
16
|
def perform(type, ids, options = {})
|
17
17
|
options[:refresh] = !Chewy.disable_refresh_async if Chewy.disable_refresh_async
|
@@ -22,7 +22,7 @@ module Chewy
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def import_scope(scope, options)
|
25
|
-
pluck_in_batches(scope, options.slice(:batch_size)).inject(true) do |result, ids|
|
25
|
+
pluck_in_batches(scope, **options.slice(:batch_size)).inject(true) do |result, ids|
|
26
26
|
objects = if options[:raw_import]
|
27
27
|
raw_default_scope_where_ids_in(ids, options[:raw_import])
|
28
28
|
else
|
@@ -25,7 +25,7 @@ module Chewy
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def import_scope(scope, options)
|
28
|
-
pluck_in_batches(scope, options.slice(:batch_size)).map do |ids|
|
28
|
+
pluck_in_batches(scope, **options.slice(:batch_size)).map do |ids|
|
29
29
|
yield grouped_objects(default_scope_where_ids_in(ids))
|
30
30
|
end.all?
|
31
31
|
end
|
@@ -89,7 +89,7 @@ module Chewy
|
|
89
89
|
|
90
90
|
if options[:fields].present? || collection.is_a?(relation_class)
|
91
91
|
collection = all_scope_where_ids_in(identify(collection)) unless collection.is_a?(relation_class)
|
92
|
-
pluck_in_batches(collection, options.slice(:fields, :batch_size, :typecast), &block)
|
92
|
+
pluck_in_batches(collection, **options.slice(:fields, :batch_size, :typecast), &block)
|
93
93
|
else
|
94
94
|
identify(collection).each_slice(options[:batch_size]) do |batch|
|
95
95
|
yield batch
|
@@ -22,7 +22,7 @@ module Chewy
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def import_scope(scope, options)
|
25
|
-
pluck_in_batches(scope, options.slice(:batch_size)).inject(true) do |result, ids|
|
25
|
+
pluck_in_batches(scope, **options.slice(:batch_size)).inject(true) do |result, ids|
|
26
26
|
result & yield(grouped_objects(default_scope_where_ids_in(ids).all))
|
27
27
|
end
|
28
28
|
end
|
@@ -54,15 +54,17 @@ module Chewy
|
|
54
54
|
|
55
55
|
def request_bodies(body)
|
56
56
|
if @bulk_size
|
57
|
+
serializer = ::Elasticsearch::API.serializer
|
57
58
|
pieces = body.each_with_object(['']) do |piece, result|
|
58
59
|
operation, meta = piece.to_a.first
|
59
60
|
data = meta.delete(:data)
|
60
|
-
piece =
|
61
|
+
piece = serializer.dump(operation => meta)
|
62
|
+
piece << "\n" << serializer.dump(data) if data.present?
|
61
63
|
|
62
64
|
if result.last.bytesize + piece.bytesize > @bulk_size
|
63
65
|
result.push(piece)
|
64
66
|
else
|
65
|
-
result[-1]
|
67
|
+
result[-1].blank? ? (result[-1] = piece) : (result[-1] << "\n" << piece)
|
66
68
|
end
|
67
69
|
end
|
68
70
|
pieces.each { |piece| piece << "\n" }
|
@@ -31,7 +31,7 @@ module Chewy
|
|
31
31
|
index_name: @type.index.derivable_name,
|
32
32
|
type_name: @type.type_name,
|
33
33
|
action: action,
|
34
|
-
references: identify(objects).map
|
34
|
+
references: identify(objects).map { |item| Base64.encode64(::Elasticsearch::API.serializer.dump(item)) },
|
35
35
|
created_at: Time.now.utc
|
36
36
|
}
|
37
37
|
end
|
@@ -66,7 +66,7 @@ module Chewy
|
|
66
66
|
def create_indexes!
|
67
67
|
Chewy::Stash::Journal.create if @options[:journal]
|
68
68
|
return if Chewy.configuration[:skip_index_creation_on_import]
|
69
|
-
@type.index.create!(
|
69
|
+
@type.index.create!(**@bulk_options.slice(:suffix)) unless @type.index.exists?
|
70
70
|
end
|
71
71
|
|
72
72
|
# The main process method. Converts passed objects to thr bulk request body,
|