chewy 7.1.0 → 7.2.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/.github/workflows/ruby.yml +58 -0
- data/.rubocop.yml +13 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +53 -0
- data/Gemfile +0 -7
- data/Guardfile +3 -1
- data/README.md +282 -245
- data/chewy.gemspec +3 -5
- data/gemfiles/rails.5.2.activerecord.gemfile +8 -14
- data/gemfiles/rails.6.0.activerecord.gemfile +8 -14
- data/gemfiles/rails.6.1.activerecord.gemfile +8 -14
- data/lib/chewy.rb +21 -75
- data/lib/chewy/config.rb +40 -40
- data/lib/chewy/errors.rb +0 -12
- data/lib/chewy/fields/base.rb +11 -1
- data/lib/chewy/fields/root.rb +3 -4
- data/lib/chewy/index.rb +46 -87
- data/lib/chewy/index/actions.rb +51 -32
- data/lib/chewy/{type → index}/adapter/active_record.rb +12 -3
- data/lib/chewy/{type → index}/adapter/base.rb +2 -3
- data/lib/chewy/{type → index}/adapter/object.rb +27 -31
- data/lib/chewy/{type → index}/adapter/orm.rb +11 -14
- data/lib/chewy/{type → index}/crutch.rb +5 -5
- data/lib/chewy/{type → index}/import.rb +36 -27
- data/lib/chewy/{type → index}/import/bulk_builder.rb +15 -13
- data/lib/chewy/{type → index}/import/bulk_request.rb +6 -6
- data/lib/chewy/{type → index}/import/journal_builder.rb +10 -10
- data/lib/chewy/{type → index}/import/routine.rb +15 -14
- data/lib/chewy/{type → index}/mapping.rb +26 -31
- data/lib/chewy/{type → index}/observe.rb +9 -19
- data/lib/chewy/index/specification.rb +1 -0
- data/lib/chewy/{type → index}/syncer.rb +60 -57
- data/lib/chewy/{type → index}/witchcraft.rb +11 -7
- data/lib/chewy/{type → index}/wrapper.rb +2 -2
- data/lib/chewy/journal.rb +8 -8
- data/lib/chewy/minitest/helpers.rb +9 -13
- data/lib/chewy/minitest/search_index_receiver.rb +22 -26
- data/lib/chewy/railtie.rb +4 -2
- data/lib/chewy/rake_helper.rb +82 -107
- data/lib/chewy/rspec/update_index.rb +47 -43
- data/lib/chewy/search.rb +4 -17
- data/lib/chewy/search/loader.rb +18 -30
- data/lib/chewy/search/parameters.rb +4 -2
- data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
- data/lib/chewy/search/parameters/source.rb +5 -1
- data/lib/chewy/search/query_proxy.rb +9 -2
- data/lib/chewy/search/request.rb +82 -86
- data/lib/chewy/search/response.rb +4 -4
- data/lib/chewy/search/scoping.rb +6 -7
- data/lib/chewy/search/scrolling.rb +11 -11
- data/lib/chewy/stash.rb +14 -22
- data/lib/chewy/strategy.rb +3 -19
- data/lib/chewy/strategy/sidekiq.rb +1 -0
- data/lib/chewy/version.rb +1 -1
- data/lib/generators/chewy/install_generator.rb +1 -1
- data/lib/tasks/chewy.rake +10 -22
- data/migration_guide.md +14 -0
- data/spec/chewy/config_spec.rb +14 -39
- data/spec/chewy/fields/base_spec.rb +412 -148
- data/spec/chewy/fields/root_spec.rb +16 -24
- data/spec/chewy/fields/time_fields_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +270 -24
- data/spec/chewy/{type → index}/adapter/active_record_spec.rb +68 -40
- data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
- data/spec/chewy/{type → index}/import/bulk_builder_spec.rb +23 -31
- data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -6
- data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -15
- data/spec/chewy/{type → index}/import/routine_spec.rb +16 -16
- data/spec/chewy/{type → index}/import_spec.rb +102 -98
- data/spec/chewy/{type → index}/mapping_spec.rb +46 -54
- data/spec/chewy/index/observe_spec.rb +116 -0
- data/spec/chewy/index/settings_spec.rb +3 -1
- data/spec/chewy/index/specification_spec.rb +7 -17
- data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
- data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
- data/spec/chewy/index/wrapper_spec.rb +100 -0
- data/spec/chewy/index_spec.rb +59 -102
- data/spec/chewy/journal_spec.rb +9 -22
- data/spec/chewy/minitest/helpers_spec.rb +13 -15
- data/spec/chewy/minitest/search_index_receiver_spec.rb +22 -26
- data/spec/chewy/multi_search_spec.rb +4 -5
- data/spec/chewy/rake_helper_spec.rb +145 -55
- data/spec/chewy/rspec/update_index_spec.rb +74 -71
- data/spec/chewy/search/loader_spec.rb +19 -37
- data/spec/chewy/search/pagination/kaminari_examples.rb +3 -5
- data/spec/chewy/search/pagination/kaminari_spec.rb +1 -1
- data/spec/chewy/search/parameters/indices_spec.rb +2 -8
- data/spec/chewy/search/parameters/order_spec.rb +1 -1
- data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
- data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
- data/spec/chewy/search/parameters/source_spec.rb +8 -2
- data/spec/chewy/search/parameters_spec.rb +12 -3
- data/spec/chewy/search/query_proxy_spec.rb +68 -17
- data/spec/chewy/search/request_spec.rb +222 -74
- data/spec/chewy/search/response_spec.rb +12 -12
- data/spec/chewy/search/scrolling_spec.rb +7 -9
- data/spec/chewy/search_spec.rb +32 -35
- data/spec/chewy/stash_spec.rb +9 -21
- data/spec/chewy/strategy/active_job_spec.rb +8 -8
- data/spec/chewy/strategy/atomic_spec.rb +9 -10
- data/spec/chewy/strategy/sidekiq_spec.rb +8 -8
- data/spec/chewy/strategy_spec.rb +19 -15
- data/spec/chewy_spec.rb +14 -100
- data/spec/spec_helper.rb +2 -21
- data/spec/support/active_record.rb +15 -5
- metadata +44 -103
- data/.circleci/config.yml +0 -214
- data/Appraisals +0 -81
- data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
- data/gemfiles/sequel.4.45.gemfile +0 -11
- data/lib/chewy/search/pagination/will_paginate.rb +0 -43
- data/lib/chewy/strategy/resque.rb +0 -27
- data/lib/chewy/strategy/shoryuken.rb +0 -40
- data/lib/chewy/type.rb +0 -120
- data/lib/chewy/type/actions.rb +0 -43
- data/lib/chewy/type/adapter/mongoid.rb +0 -67
- data/lib/chewy/type/adapter/sequel.rb +0 -93
- data/lib/sequel/plugins/chewy_observe.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
- data/spec/chewy/strategy/resque_spec.rb +0 -46
- data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
- data/spec/chewy/type/actions_spec.rb +0 -50
- data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
- data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
- data/spec/chewy/type/observe_spec.rb +0 -137
- data/spec/chewy/type/wrapper_spec.rb +0 -100
- data/spec/chewy/type_spec.rb +0 -55
- data/spec/support/mongoid.rb +0 -93
- data/spec/support/sequel.rb +0 -80
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
require 'chewy/
|
|
1
|
+
require 'chewy/index/adapter/base'
|
|
2
2
|
|
|
3
3
|
module Chewy
|
|
4
|
-
class
|
|
4
|
+
class Index
|
|
5
5
|
module Adapter
|
|
6
6
|
class Orm < Base
|
|
7
7
|
attr_reader :default_scope
|
|
@@ -54,24 +54,23 @@ module Chewy
|
|
|
54
54
|
#
|
|
55
55
|
# users = User.all
|
|
56
56
|
# users.each { |user| user.destroy if user.inactive? }
|
|
57
|
-
# UsersIndex
|
|
57
|
+
# UsersIndex.import users # inactive users will be deleted from index
|
|
58
58
|
# # or
|
|
59
|
-
# UsersIndex
|
|
59
|
+
# UsersIndex.import users.map(&:id) # deleted user ids will be deleted from index
|
|
60
60
|
#
|
|
61
61
|
# Also there is custom type option `delete_if`. It it returns `true`
|
|
62
62
|
# object will be deleted from index. Note that if this option is defined and
|
|
63
63
|
# return `false` Chewy will still check `destroyed?` method. This is useful
|
|
64
64
|
# for paranoid objects deleting implementation.
|
|
65
65
|
#
|
|
66
|
-
#
|
|
67
|
-
#
|
|
68
|
-
# end
|
|
66
|
+
# index_scope User, delete_if: ->{ deleted_at }
|
|
67
|
+
# ...
|
|
69
68
|
#
|
|
70
69
|
# users = User.all
|
|
71
70
|
# users.each { |user| user.deleted_at = Time.now }
|
|
72
|
-
# UsersIndex
|
|
71
|
+
# UsersIndex.import users # paranoid deleted users will be deleted from index
|
|
73
72
|
# # or
|
|
74
|
-
# UsersIndex
|
|
73
|
+
# UsersIndex.import users.map(&:id) # user ids will be deleted from index
|
|
75
74
|
#
|
|
76
75
|
def import(*args, &block)
|
|
77
76
|
collection, options = import_args(*args)
|
|
@@ -92,16 +91,14 @@ module Chewy
|
|
|
92
91
|
collection = all_scope_where_ids_in(identify(collection)) unless collection.is_a?(relation_class)
|
|
93
92
|
pluck_in_batches(collection, **options.slice(:fields, :batch_size, :typecast), &block)
|
|
94
93
|
else
|
|
95
|
-
identify(collection).each_slice(options[:batch_size])
|
|
96
|
-
yield batch
|
|
97
|
-
end
|
|
94
|
+
identify(collection).each_slice(options[:batch_size], &block)
|
|
98
95
|
end
|
|
99
96
|
end
|
|
100
97
|
alias_method :import_references, :import_fields
|
|
101
98
|
|
|
102
99
|
def load(ids, **options)
|
|
103
100
|
scope = all_scope_where_ids_in(ids)
|
|
104
|
-
additional_scope = options[options[:
|
|
101
|
+
additional_scope = options[options[:_index].to_sym].try(:[], :scope) || options[:scope]
|
|
105
102
|
|
|
106
103
|
loaded_objects = load_scope_objects(scope, additional_scope)
|
|
107
104
|
.index_by do |object|
|
|
@@ -115,7 +112,7 @@ module Chewy
|
|
|
115
112
|
|
|
116
113
|
def import_objects(collection, options)
|
|
117
114
|
collection_ids = identify(collection)
|
|
118
|
-
hash =
|
|
115
|
+
hash = collection_ids.map(&:to_s).zip(collection).to_h
|
|
119
116
|
|
|
120
117
|
indexed = collection_ids.each_slice(options[:batch_size]).map do |ids|
|
|
121
118
|
batch = if options[:raw_import]
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Crutch
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
@@ -9,13 +9,13 @@ module Chewy
|
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
class Crutches
|
|
12
|
-
def initialize(
|
|
13
|
-
@
|
|
12
|
+
def initialize(index, collection)
|
|
13
|
+
@index = index
|
|
14
14
|
@collection = collection
|
|
15
|
-
@
|
|
15
|
+
@index._crutches.each_key do |name|
|
|
16
16
|
singleton_class.class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
|
17
17
|
def #{name}
|
|
18
|
-
@#{name} ||= @
|
|
18
|
+
@#{name} ||= @index._crutches[:#{name}].call @collection
|
|
19
19
|
end
|
|
20
20
|
METHOD
|
|
21
21
|
end
|
|
@@ -1,39 +1,39 @@
|
|
|
1
|
-
require 'chewy/
|
|
2
|
-
require 'chewy/
|
|
3
|
-
require 'chewy/
|
|
4
|
-
require 'chewy/
|
|
1
|
+
require 'chewy/index/import/journal_builder'
|
|
2
|
+
require 'chewy/index/import/bulk_builder'
|
|
3
|
+
require 'chewy/index/import/bulk_request'
|
|
4
|
+
require 'chewy/index/import/routine'
|
|
5
5
|
|
|
6
6
|
module Chewy
|
|
7
|
-
class
|
|
7
|
+
class Index
|
|
8
8
|
module Import
|
|
9
9
|
extend ActiveSupport::Concern
|
|
10
10
|
|
|
11
|
-
IMPORT_WORKER = lambda do |
|
|
12
|
-
::Process.setproctitle("chewy [#{
|
|
13
|
-
routine = Routine.new(
|
|
14
|
-
|
|
11
|
+
IMPORT_WORKER = lambda do |index, options, total, ids, iteration|
|
|
12
|
+
::Process.setproctitle("chewy [#{index}]: import data (#{iteration + 1}/#{total})")
|
|
13
|
+
routine = Routine.new(index, **options)
|
|
14
|
+
index.adapter.import(*ids, routine.options) do |action_objects|
|
|
15
15
|
routine.process(**action_objects)
|
|
16
16
|
end
|
|
17
17
|
{errors: routine.errors, import: routine.stats, leftovers: routine.leftovers}
|
|
18
18
|
end
|
|
19
19
|
|
|
20
|
-
LEFTOVERS_WORKER = lambda do |
|
|
21
|
-
::Process.setproctitle("chewy [#{
|
|
22
|
-
routine = Routine.new(
|
|
20
|
+
LEFTOVERS_WORKER = lambda do |index, options, total, body, iteration|
|
|
21
|
+
::Process.setproctitle("chewy [#{index}]: import leftovers (#{iteration + 1}/#{total})")
|
|
22
|
+
routine = Routine.new(index, **options)
|
|
23
23
|
routine.perform_bulk(body)
|
|
24
24
|
routine.errors
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
module ClassMethods
|
|
28
28
|
# @!method import(*collection, **options)
|
|
29
|
-
# Basically, one of the main methods for
|
|
30
|
-
# to the index
|
|
29
|
+
# Basically, one of the main methods for an index. Performs any objects import
|
|
30
|
+
# to the index. Does all the objects handling routines.
|
|
31
31
|
# Performs document import by utilizing bulk API. Bulk size and objects batch
|
|
32
32
|
# size are controlled by the corresponding options.
|
|
33
33
|
#
|
|
34
34
|
# It accepts ORM/ODM objects, PORO, hashes, ids which are used by adapter to
|
|
35
|
-
# fetch objects from the source
|
|
36
|
-
# passed objects from the index if they are not in the default
|
|
35
|
+
# fetch objects from the source depending on the used adapter. It destroys
|
|
36
|
+
# passed objects from the index if they are not in the default scope
|
|
37
37
|
# or marked for destruction.
|
|
38
38
|
#
|
|
39
39
|
# It handles parent-child relationships: if the object parent_id has been
|
|
@@ -51,15 +51,15 @@ module Chewy
|
|
|
51
51
|
#
|
|
52
52
|
# Utilizes `ActiveSupport::Notifications`, so it is possible to get imported
|
|
53
53
|
# objects later by listening to the `import_objects.chewy` queue. It is also
|
|
54
|
-
# possible to get the list of
|
|
54
|
+
# possible to get the list of occurred errors from the payload if something
|
|
55
55
|
# went wrong.
|
|
56
56
|
#
|
|
57
57
|
# Import can also be run in parallel using the Parallel gem functionality.
|
|
58
58
|
#
|
|
59
59
|
# @example
|
|
60
|
-
# UsersIndex
|
|
61
|
-
# UsersIndex
|
|
62
|
-
# UsersIndex
|
|
60
|
+
# UsersIndex.import(parallel: true) # imports everything in parallel with automatic workers number
|
|
61
|
+
# UsersIndex.import(parallel: 3) # using 3 workers
|
|
62
|
+
# UsersIndex.import(parallel: {in_threads: 10}) # in 10 threads
|
|
63
63
|
#
|
|
64
64
|
# @see https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
|
|
65
65
|
# @param collection [Array<Object>] and array or anything to import
|
|
@@ -87,6 +87,7 @@ module Chewy
|
|
|
87
87
|
def import!(*args)
|
|
88
88
|
errors = import_routine(*args)
|
|
89
89
|
raise Chewy::ImportFailed.new(self, errors) if errors.present?
|
|
90
|
+
|
|
90
91
|
true
|
|
91
92
|
end
|
|
92
93
|
|
|
@@ -94,7 +95,7 @@ module Chewy
|
|
|
94
95
|
# `bulk_size` and `suffix`.
|
|
95
96
|
#
|
|
96
97
|
# @see https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
|
|
97
|
-
# @see Chewy::
|
|
98
|
+
# @see Chewy::Index::Import::BulkRequest
|
|
98
99
|
# @param options [Hash{Symbol => Object}] besides specific import options, it accepts all the options suitable for the bulk API call like `refresh` or `timeout`
|
|
99
100
|
# @option options [String] suffix bulk API chunk size in bytes; if passed, the request is performed several times for each chunk, empty by default
|
|
100
101
|
# @option options [Integer] bulk_size bulk API chunk size in bytes; if passed, the request is performed several times for each chunk, empty by default
|
|
@@ -111,11 +112,11 @@ module Chewy
|
|
|
111
112
|
# or normal composing under the hood.
|
|
112
113
|
#
|
|
113
114
|
# @param object [Object] a data source object
|
|
114
|
-
# @param crutches [Object] optional crutches object; if
|
|
115
|
+
# @param crutches [Object] optional crutches object; if omitted - a crutch for the single passed object is created as a fallback
|
|
115
116
|
# @param fields [Array<Symbol>] and array of fields to restrict the generated document
|
|
116
117
|
# @return [Hash] a JSON-ready hash
|
|
117
118
|
def compose(object, crutches = nil, fields: [])
|
|
118
|
-
crutches ||= Chewy::
|
|
119
|
+
crutches ||= Chewy::Index::Crutch::Crutches.new self, [object]
|
|
119
120
|
|
|
120
121
|
if witchcraft? && root.children.present?
|
|
121
122
|
cauldron(fields: fields).brew(object, crutches)
|
|
@@ -148,7 +149,7 @@ module Chewy
|
|
|
148
149
|
end
|
|
149
150
|
|
|
150
151
|
def import_linear(objects, routine)
|
|
151
|
-
ActiveSupport::Notifications.instrument 'import_objects.chewy',
|
|
152
|
+
ActiveSupport::Notifications.instrument 'import_objects.chewy', index: self do |payload|
|
|
152
153
|
adapter.import(*objects, routine.options) do |action_objects|
|
|
153
154
|
routine.process(**action_objects)
|
|
154
155
|
end
|
|
@@ -162,17 +163,25 @@ module Chewy
|
|
|
162
163
|
def import_parallel(objects, routine)
|
|
163
164
|
raise "The `parallel` gem is required for parallel import, please add `gem 'parallel'` to your Gemfile" unless '::Parallel'.safe_constantize
|
|
164
165
|
|
|
165
|
-
ActiveSupport::Notifications.instrument 'import_objects.chewy',
|
|
166
|
+
ActiveSupport::Notifications.instrument 'import_objects.chewy', index: self do |payload|
|
|
166
167
|
batches = adapter.import_references(*objects, routine.options.slice(:batch_size)).to_a
|
|
167
168
|
|
|
168
169
|
::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
|
|
169
|
-
results = ::Parallel.map_with_index(
|
|
170
|
+
results = ::Parallel.map_with_index(
|
|
171
|
+
batches,
|
|
172
|
+
routine.parallel_options,
|
|
173
|
+
&IMPORT_WORKER.curry[self, routine.options, batches.size]
|
|
174
|
+
)
|
|
170
175
|
::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
|
|
171
176
|
errors, import, leftovers = process_parallel_import_results(results)
|
|
172
177
|
|
|
173
178
|
if leftovers.present?
|
|
174
179
|
batches = leftovers.each_slice(routine.options[:batch_size])
|
|
175
|
-
results = ::Parallel.map_with_index(
|
|
180
|
+
results = ::Parallel.map_with_index(
|
|
181
|
+
batches,
|
|
182
|
+
routine.parallel_options,
|
|
183
|
+
&LEFTOVERS_WORKER.curry[self, routine.options, batches.size]
|
|
184
|
+
)
|
|
176
185
|
errors.concat(results.flatten(1))
|
|
177
186
|
end
|
|
178
187
|
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Import
|
|
4
4
|
# This class purpose is to build ES client-acceptable bulk
|
|
5
5
|
# request body from the passed objects for index and deletion.
|
|
@@ -9,13 +9,13 @@ module Chewy
|
|
|
9
9
|
# If fields are passed - it creates partial update entries except for
|
|
10
10
|
# the cases when the type has parent and parent_id has been changed.
|
|
11
11
|
class BulkBuilder
|
|
12
|
-
# @param
|
|
13
|
-
# @param
|
|
12
|
+
# @param index [Chewy::Index] desired index
|
|
13
|
+
# @param to_index [Array<Object>] objects to index
|
|
14
14
|
# @param delete [Array<Object>] objects or ids to delete
|
|
15
15
|
# @param fields [Array<Symbol, String>] and array of fields for documents update
|
|
16
|
-
def initialize(
|
|
17
|
-
@type = type
|
|
16
|
+
def initialize(index, to_index: [], delete: [], fields: [])
|
|
18
17
|
@index = index
|
|
18
|
+
@to_index = to_index
|
|
19
19
|
@delete = delete
|
|
20
20
|
@fields = fields.map!(&:to_sym)
|
|
21
21
|
end
|
|
@@ -24,7 +24,7 @@ module Chewy
|
|
|
24
24
|
# @see https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
|
|
25
25
|
# @return [Array<Hash>] bulk body
|
|
26
26
|
def bulk_body
|
|
27
|
-
@bulk_body ||= @
|
|
27
|
+
@bulk_body ||= @to_index.flat_map(&method(:index_entry)).concat(
|
|
28
28
|
@delete.flat_map(&method(:delete_entry))
|
|
29
29
|
)
|
|
30
30
|
end
|
|
@@ -40,7 +40,7 @@ module Chewy
|
|
|
40
40
|
private
|
|
41
41
|
|
|
42
42
|
def crutches
|
|
43
|
-
@crutches ||= Chewy::
|
|
43
|
+
@crutches ||= Chewy::Index::Crutch::Crutches.new @index, @to_index
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def parents
|
|
@@ -53,7 +53,7 @@ module Chewy
|
|
|
53
53
|
ids.concat(@delete.map do |object|
|
|
54
54
|
object.respond_to?(:id) ? object.id : object
|
|
55
55
|
end)
|
|
56
|
-
@
|
|
56
|
+
@index.filter(ids: {values: ids}).order('_doc').pluck(:_id, :_parent).to_h
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -67,14 +67,15 @@ module Chewy
|
|
|
67
67
|
end
|
|
68
68
|
|
|
69
69
|
if parent && entry[:parent].to_s != parent
|
|
70
|
-
entry[:data] = @
|
|
70
|
+
entry[:data] = @index.compose(object, crutches)
|
|
71
71
|
[{delete: entry.except(:data).merge(parent: parent)}, {index: entry}]
|
|
72
72
|
elsif @fields.present?
|
|
73
73
|
return [] unless entry[:_id]
|
|
74
|
-
|
|
74
|
+
|
|
75
|
+
entry[:data] = {doc: @index.compose(object, crutches, fields: @fields)}
|
|
75
76
|
[{update: entry}]
|
|
76
77
|
else
|
|
77
|
-
entry[:data] = @
|
|
78
|
+
entry[:data] = @index.compose(object, crutches)
|
|
78
79
|
[{index: entry}]
|
|
79
80
|
end
|
|
80
81
|
end
|
|
@@ -89,6 +90,7 @@ module Chewy
|
|
|
89
90
|
if parents
|
|
90
91
|
parent = entry[:_id].present? && parents[entry[:_id].to_s]
|
|
91
92
|
return [] unless parent
|
|
93
|
+
|
|
92
94
|
entry[:parent] = parent
|
|
93
95
|
end
|
|
94
96
|
|
|
@@ -107,14 +109,14 @@ module Chewy
|
|
|
107
109
|
end
|
|
108
110
|
|
|
109
111
|
def index_object_ids
|
|
110
|
-
@index_object_ids ||= @
|
|
112
|
+
@index_object_ids ||= @to_index.each_with_object({}) do |object, result|
|
|
111
113
|
id = entry_id(object)
|
|
112
114
|
result[object] = id if id.present?
|
|
113
115
|
end
|
|
114
116
|
end
|
|
115
117
|
|
|
116
118
|
def type_root
|
|
117
|
-
@type_root ||= @
|
|
119
|
+
@type_root ||= @index.root
|
|
118
120
|
end
|
|
119
121
|
end
|
|
120
122
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Import
|
|
4
4
|
# Adds additional features to elasticsearch-api bulk method:
|
|
5
5
|
# * supports Chewy index suffix if necessary;
|
|
@@ -10,12 +10,12 @@ module Chewy
|
|
|
10
10
|
#
|
|
11
11
|
# @see https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
|
|
12
12
|
class BulkRequest
|
|
13
|
-
# @param
|
|
13
|
+
# @param index [Chewy::Index] an index for the request
|
|
14
14
|
# @param suffix [String] an index name optional suffix
|
|
15
15
|
# @param bulk_size [Integer] bulk size in bytes
|
|
16
16
|
# @param bulk_options [Hash] options passed to the elasticsearch-api bulk method
|
|
17
|
-
def initialize(
|
|
18
|
-
@
|
|
17
|
+
def initialize(index, suffix: nil, bulk_size: nil, **bulk_options)
|
|
18
|
+
@index = index
|
|
19
19
|
@suffix = suffix
|
|
20
20
|
@bulk_size = bulk_size - 1.kilobyte if bulk_size # 1 kilobyte for request header and newlines
|
|
21
21
|
@bulk_options = bulk_options
|
|
@@ -33,7 +33,7 @@ module Chewy
|
|
|
33
33
|
return [] if body.blank?
|
|
34
34
|
|
|
35
35
|
request_bodies(body).each_with_object([]) do |request_body, results|
|
|
36
|
-
response = @
|
|
36
|
+
response = @index.client.bulk request_base.merge(body: request_body) if request_body.present?
|
|
37
37
|
|
|
38
38
|
next unless response.try(:[], 'errors')
|
|
39
39
|
|
|
@@ -47,7 +47,7 @@ module Chewy
|
|
|
47
47
|
|
|
48
48
|
def request_base
|
|
49
49
|
@request_base ||= {
|
|
50
|
-
index: @
|
|
50
|
+
index: @index.index_name(suffix: @suffix)
|
|
51
51
|
}.merge!(@bulk_options)
|
|
52
52
|
end
|
|
53
53
|
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Import
|
|
4
4
|
class JournalBuilder
|
|
5
|
-
def initialize(
|
|
6
|
-
@type = type
|
|
5
|
+
def initialize(index, to_index: [], delete: [])
|
|
7
6
|
@index = index
|
|
7
|
+
@to_index = to_index
|
|
8
8
|
@delete = delete
|
|
9
9
|
end
|
|
10
10
|
|
|
11
11
|
def bulk_body
|
|
12
|
-
Chewy::
|
|
13
|
-
Chewy::Stash::Journal
|
|
14
|
-
|
|
15
|
-
entries(:index, @
|
|
12
|
+
Chewy::Index::Import::BulkBuilder.new(
|
|
13
|
+
Chewy::Stash::Journal,
|
|
14
|
+
to_index: [
|
|
15
|
+
entries(:index, @to_index),
|
|
16
16
|
entries(:delete, @delete)
|
|
17
17
|
].compact
|
|
18
18
|
).bulk_body.each do |item|
|
|
@@ -26,9 +26,9 @@ module Chewy
|
|
|
26
26
|
|
|
27
27
|
def entries(action, objects)
|
|
28
28
|
return unless objects.present?
|
|
29
|
+
|
|
29
30
|
{
|
|
30
|
-
index_name: @
|
|
31
|
-
type_name: @type.type_name,
|
|
31
|
+
index_name: @index.derivable_name,
|
|
32
32
|
action: action,
|
|
33
33
|
references: identify(objects).map { |item| Base64.encode64(::Elasticsearch::API.serializer.dump(item)) },
|
|
34
34
|
created_at: Time.now.utc
|
|
@@ -36,7 +36,7 @@ module Chewy
|
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
def identify(objects)
|
|
39
|
-
@
|
|
39
|
+
@index.adapter.identify(objects)
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Import
|
|
4
4
|
# This class performs the import routine for the options and objects given.
|
|
5
5
|
#
|
|
@@ -20,7 +20,7 @@ module Chewy
|
|
|
20
20
|
# when the document doesn't exist only if `update_failover` option is true. In order to
|
|
21
21
|
# restore, it indexes such an objects completely on the next iteration.
|
|
22
22
|
#
|
|
23
|
-
# @see Chewy::
|
|
23
|
+
# @see Chewy::Index::Import::ClassMethods#import
|
|
24
24
|
class Routine
|
|
25
25
|
BULK_OPTIONS = %i[
|
|
26
26
|
suffix bulk_size
|
|
@@ -33,18 +33,18 @@ module Chewy
|
|
|
33
33
|
refresh: true,
|
|
34
34
|
update_fields: [],
|
|
35
35
|
update_failover: true,
|
|
36
|
-
batch_size: Chewy::
|
|
36
|
+
batch_size: Chewy::Index::Adapter::Base::BATCH_SIZE
|
|
37
37
|
}.freeze
|
|
38
38
|
|
|
39
39
|
attr_reader :options, :parallel_options, :errors, :stats, :leftovers
|
|
40
40
|
|
|
41
41
|
# Basically, processes passed options, extracting bulk request specific options.
|
|
42
|
-
# @param
|
|
43
|
-
# @param options [Hash] import options, see {Chewy::
|
|
44
|
-
def initialize(
|
|
45
|
-
@
|
|
42
|
+
# @param index [Chewy::Index] chewy index
|
|
43
|
+
# @param options [Hash] import options, see {Chewy::Index::Import::ClassMethods#import}
|
|
44
|
+
def initialize(index, **options)
|
|
45
|
+
@index = index
|
|
46
46
|
@options = options
|
|
47
|
-
@options.reverse_merge!(@
|
|
47
|
+
@options.reverse_merge!(@index._default_import_options)
|
|
48
48
|
@options.reverse_merge!(journal: Chewy.configuration[:journal])
|
|
49
49
|
@options.reverse_merge!(DEFAULT_OPTIONS)
|
|
50
50
|
@bulk_options = @options.slice(*BULK_OPTIONS)
|
|
@@ -61,12 +61,13 @@ module Chewy
|
|
|
61
61
|
@leftovers = []
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
-
# Creates the journal index and the
|
|
64
|
+
# Creates the journal index and the corresponding index if necessary.
|
|
65
65
|
# @return [Object] whatever
|
|
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
|
-
|
|
69
|
+
|
|
70
|
+
@index.create!(**@bulk_options.slice(:suffix)) unless @index.exists?
|
|
70
71
|
end
|
|
71
72
|
|
|
72
73
|
# The main process method. Converts passed objects to the bulk request body,
|
|
@@ -77,11 +78,11 @@ module Chewy
|
|
|
77
78
|
# @param delete [Array<Object>] any acceptable objects for deleting
|
|
78
79
|
# @return [true, false] the result of the request, true if no errors
|
|
79
80
|
def process(index: [], delete: [])
|
|
80
|
-
bulk_builder = BulkBuilder.new(@
|
|
81
|
+
bulk_builder = BulkBuilder.new(@index, to_index: index, delete: delete, fields: @options[:update_fields])
|
|
81
82
|
bulk_body = bulk_builder.bulk_body
|
|
82
83
|
|
|
83
84
|
if @options[:journal]
|
|
84
|
-
journal_builder = JournalBuilder.new(@
|
|
85
|
+
journal_builder = JournalBuilder.new(@index, to_index: index, delete: delete)
|
|
85
86
|
bulk_body.concat(journal_builder.bulk_body)
|
|
86
87
|
end
|
|
87
88
|
|
|
@@ -126,11 +127,11 @@ module Chewy
|
|
|
126
127
|
errors_to_cleanup.each { |error| errors.delete(error) }
|
|
127
128
|
|
|
128
129
|
failed_objects = index_objects_by_id.values_at(*failed_ids_for_reimport)
|
|
129
|
-
BulkBuilder.new(@
|
|
130
|
+
BulkBuilder.new(@index, to_index: failed_objects).bulk_body
|
|
130
131
|
end
|
|
131
132
|
|
|
132
133
|
def bulk
|
|
133
|
-
@bulk ||= BulkRequest.new(@
|
|
134
|
+
@bulk ||= BulkRequest.new(@index, **@bulk_options)
|
|
134
135
|
end
|
|
135
136
|
end
|
|
136
137
|
end
|