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,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Mapping
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
@@ -13,42 +13,39 @@ module Chewy
|
|
|
13
13
|
end
|
|
14
14
|
|
|
15
15
|
module ClassMethods
|
|
16
|
-
# Defines root object for mapping and is optional for
|
|
16
|
+
# Defines root object for mapping and is optional for index
|
|
17
17
|
# definition. Use it only if you need to pass options for root
|
|
18
18
|
# object mapping, such as `date_detection` or `dynamic_date_formats`
|
|
19
19
|
#
|
|
20
20
|
# @example
|
|
21
21
|
# class UsersIndex < Chewy::Index
|
|
22
|
-
#
|
|
23
|
-
#
|
|
24
|
-
#
|
|
25
|
-
# end
|
|
22
|
+
# index_scope User
|
|
23
|
+
# # root object defined implicitly and optionless for current type
|
|
24
|
+
# field :full_name, type: 'keyword'
|
|
26
25
|
# end
|
|
27
26
|
#
|
|
28
27
|
# class CarsIndex < Chewy::Index
|
|
29
|
-
#
|
|
30
|
-
#
|
|
31
|
-
#
|
|
32
|
-
#
|
|
33
|
-
# end
|
|
28
|
+
# index_scope Car
|
|
29
|
+
# # explicit root definition with additional options
|
|
30
|
+
# root dynamic_date_formats: ['yyyy-MM-dd'] do
|
|
31
|
+
# field :model_name, type: 'keyword'
|
|
34
32
|
# end
|
|
35
33
|
# end
|
|
36
34
|
#
|
|
37
35
|
def root(**options)
|
|
38
|
-
self.root_object ||= Chewy::Fields::Root.new(
|
|
36
|
+
self.root_object ||= Chewy::Fields::Root.new(:root, **Chewy.default_root_options.merge(options))
|
|
39
37
|
root_object.update_options!(**options)
|
|
40
38
|
yield if block_given?
|
|
41
39
|
root_object
|
|
42
40
|
end
|
|
43
41
|
|
|
44
|
-
# Defines mapping field for
|
|
42
|
+
# Defines mapping field for index
|
|
45
43
|
#
|
|
46
44
|
# @example
|
|
47
45
|
# class UsersIndex < Chewy::Index
|
|
48
|
-
#
|
|
49
|
-
#
|
|
50
|
-
#
|
|
51
|
-
# end
|
|
46
|
+
# index_scope User
|
|
47
|
+
# # passing all the options to field definition:
|
|
48
|
+
# field :full_name, analyzer: 'special'
|
|
52
49
|
# end
|
|
53
50
|
#
|
|
54
51
|
# The `type` is optional and defaults to `string` if not defined:
|
|
@@ -138,14 +135,13 @@ module Chewy
|
|
|
138
135
|
# # Suppose that a user has posts and each post has ratings
|
|
139
136
|
# # avg_post_rating is the mean of all ratings
|
|
140
137
|
# class UsersIndex < Chewy::Index
|
|
141
|
-
#
|
|
142
|
-
#
|
|
143
|
-
#
|
|
144
|
-
#
|
|
145
|
-
#
|
|
146
|
-
#
|
|
147
|
-
#
|
|
148
|
-
# end
|
|
138
|
+
# index_scope User
|
|
139
|
+
# field :posts do
|
|
140
|
+
# field :rating
|
|
141
|
+
# end
|
|
142
|
+
#
|
|
143
|
+
# agg :avg_rating do
|
|
144
|
+
# { avg: { field: 'posts.rating' } }
|
|
149
145
|
# end
|
|
150
146
|
# end
|
|
151
147
|
def agg(name, &block)
|
|
@@ -157,11 +153,10 @@ module Chewy
|
|
|
157
153
|
#
|
|
158
154
|
# @example
|
|
159
155
|
# class CarsIndex < Chewy::Index
|
|
160
|
-
#
|
|
161
|
-
#
|
|
162
|
-
#
|
|
163
|
-
#
|
|
164
|
-
# end
|
|
156
|
+
# index_scope Car
|
|
157
|
+
# template 'model.*', type: 'text', analyzer: 'special'
|
|
158
|
+
# field 'model', type: 'object' # here we can put { de: 'Der Mercedes', en: 'Mercedes' }
|
|
159
|
+
# # and template will be applied to this field
|
|
165
160
|
# end
|
|
166
161
|
#
|
|
167
162
|
# Name for each template is generated with the following
|
|
@@ -172,7 +167,7 @@ module Chewy
|
|
|
172
167
|
# template 'title.*', mapping_hash # dot in template causes "path_match" using
|
|
173
168
|
# template /tit.+/, mapping_hash # using "match_pattern": "regexp"
|
|
174
169
|
# template /title\..+/, mapping_hash # "\." - escaped dot causes "path_match" using
|
|
175
|
-
# template /tit.+/, type: 'text', mapping_hash # "match_mapping_type" as
|
|
170
|
+
# template /tit.+/, type: 'text', mapping_hash # "match_mapping_type" as an optional second argument
|
|
176
171
|
# template template42: {match: 'hello*', mapping: {type: 'object'}} # or even pass a template as is
|
|
177
172
|
#
|
|
178
173
|
def template(*args)
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
module Observe
|
|
4
4
|
extend ActiveSupport::Concern
|
|
5
5
|
|
|
6
6
|
module Helpers
|
|
7
|
-
def update_proc(
|
|
7
|
+
def update_proc(index_name, *args, &block)
|
|
8
8
|
options = args.extract_options!
|
|
9
9
|
method = args.first
|
|
10
10
|
|
|
11
11
|
proc do
|
|
12
|
-
reference = if
|
|
13
|
-
if
|
|
14
|
-
instance_exec(&
|
|
12
|
+
reference = if index_name.is_a?(Proc)
|
|
13
|
+
if index_name.arity.zero?
|
|
14
|
+
instance_exec(&index_name)
|
|
15
15
|
else
|
|
16
|
-
|
|
16
|
+
index_name.call(self)
|
|
17
17
|
end
|
|
18
18
|
else
|
|
19
|
-
|
|
19
|
+
index_name
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
index = Chewy.derive_name(reference)
|
|
23
23
|
|
|
24
24
|
next if Chewy.strategy.current.name == :bypass
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ module Chewy
|
|
|
31
31
|
instance_eval(&block)
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
index.update_index(backreference, options)
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
@@ -47,16 +47,6 @@ module Chewy
|
|
|
47
47
|
|
|
48
48
|
extend Helpers
|
|
49
49
|
|
|
50
|
-
module MongoidMethods
|
|
51
|
-
def update_index(type_name, *args, &block)
|
|
52
|
-
callback_options = Observe.extract_callback_options!(args)
|
|
53
|
-
update_proc = Observe.update_proc(type_name, *args, &block)
|
|
54
|
-
|
|
55
|
-
after_save(callback_options, &update_proc)
|
|
56
|
-
after_destroy(callback_options, &update_proc)
|
|
57
|
-
end
|
|
58
|
-
end
|
|
59
|
-
|
|
60
50
|
module ActiveRecordMethods
|
|
61
51
|
def update_index(type_name, *args, &block)
|
|
62
52
|
callback_options = Observe.extract_callback_options!(args)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module Chewy
|
|
2
|
-
class
|
|
2
|
+
class Index
|
|
3
3
|
# This class is able to find missing and outdated documents in the ES
|
|
4
4
|
# comparing ids from the data source and the ES index. Also, if `outdated_sync_field`
|
|
5
5
|
# exists in the index definition, it performs comparison of this field
|
|
@@ -9,10 +9,10 @@ module Chewy
|
|
|
9
9
|
# should be reindexed.
|
|
10
10
|
#
|
|
11
11
|
# To fetch necessary data from the source it uses adapter method
|
|
12
|
-
# {Chewy::
|
|
12
|
+
# {Chewy::Index::Adapter::Base#import_fields}, in case when the Object
|
|
13
13
|
# adapter is used it makes sense to read corresponding documentation.
|
|
14
14
|
#
|
|
15
|
-
# If `parallel` option is passed to the initializer - it will fetch
|
|
15
|
+
# If `parallel` option is passed to the initializer - it will fetch source and
|
|
16
16
|
# index data in parallel and then perform outdated objects calculation in
|
|
17
17
|
# parallel processes. Also, further import (if required) will be performed
|
|
18
18
|
# in parallel as well.
|
|
@@ -24,17 +24,17 @@ module Chewy
|
|
|
24
24
|
# ATTENTION: synchronization may be slow in case when synchronized tables
|
|
25
25
|
# are missing compound index on primary key and `outdated_sync_field`.
|
|
26
26
|
#
|
|
27
|
-
# @see Chewy::
|
|
27
|
+
# @see Chewy::Index::Actions::ClassMethods#sync
|
|
28
28
|
class Syncer
|
|
29
29
|
DEFAULT_SYNC_BATCH_SIZE = 20_000
|
|
30
|
-
ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z
|
|
31
|
-
OUTDATED_IDS_WORKER = lambda do |outdated_sync_field_type, source_data_hash,
|
|
32
|
-
::Process.setproctitle("chewy [#{
|
|
30
|
+
ISO_DATETIME = /\A(\d{4})-(\d\d)-(\d\d) (\d\d):(\d\d):(\d\d)(\.\d+)?\z/.freeze
|
|
31
|
+
OUTDATED_IDS_WORKER = lambda do |outdated_sync_field_type, source_data_hash, index, total, index_data|
|
|
32
|
+
::Process.setproctitle("chewy [#{index}]: sync outdated calculation (#{::Parallel.worker_number + 1}/#{total})") if index
|
|
33
33
|
index_data.each_with_object([]) do |(id, index_sync_value), result|
|
|
34
34
|
next unless source_data_hash[id]
|
|
35
35
|
|
|
36
36
|
outdated = if outdated_sync_field_type == 'date'
|
|
37
|
-
!Chewy::
|
|
37
|
+
!Chewy::Index::Syncer.dates_equal(typecast_date(source_data_hash[id]), Time.iso8601(index_sync_value))
|
|
38
38
|
else
|
|
39
39
|
source_data_hash[id] != index_sync_value
|
|
40
40
|
end
|
|
@@ -42,8 +42,8 @@ module Chewy
|
|
|
42
42
|
result.push(id) if outdated
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
|
-
SOURCE_OR_INDEX_DATA_WORKER = lambda do |syncer,
|
|
46
|
-
::Process.setproctitle("chewy [#{
|
|
45
|
+
SOURCE_OR_INDEX_DATA_WORKER = lambda do |syncer, index, kind|
|
|
46
|
+
::Process.setproctitle("chewy [#{index}]: sync fetching data (#{kind})")
|
|
47
47
|
result = case kind
|
|
48
48
|
when :source
|
|
49
49
|
syncer.send(:fetch_source_data)
|
|
@@ -56,7 +56,10 @@ module Chewy
|
|
|
56
56
|
def self.typecast_date(string)
|
|
57
57
|
if string.is_a?(String) && (match = ISO_DATETIME.match(string))
|
|
58
58
|
microsec = (match[7].to_r * 1_000_000).to_i
|
|
59
|
-
|
|
59
|
+
day = "#{match[1]}-#{match[2]}-#{match[3]}"
|
|
60
|
+
time_with_seconds = "#{match[4]}:#{match[5]}:#{match[6]}"
|
|
61
|
+
microseconds = format('%06d', microsec)
|
|
62
|
+
date = "#{day}T#{time_with_seconds}.#{microseconds}+00:00"
|
|
60
63
|
Time.iso8601(date)
|
|
61
64
|
else
|
|
62
65
|
string
|
|
@@ -68,18 +71,10 @@ module Chewy
|
|
|
68
71
|
[one.to_i, one.usec / 1000] == [two.to_i, two.usec / 1000]
|
|
69
72
|
end
|
|
70
73
|
|
|
71
|
-
#
|
|
72
|
-
# milliseconds, so ES stored time with the seconds precision.
|
|
73
|
-
if ActiveSupport::VERSION::STRING < '4.1.0'
|
|
74
|
-
def self.dates_equal(one, two)
|
|
75
|
-
one.to_i == two.to_i
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
# @param type [Chewy::Type] chewy type
|
|
74
|
+
# @param index [Chewy::Index] chewy index
|
|
80
75
|
# @param parallel [true, Integer, Hash] options for parallel execution or the number of processes
|
|
81
|
-
def initialize(
|
|
82
|
-
@
|
|
76
|
+
def initialize(index, parallel: nil)
|
|
77
|
+
@index = index
|
|
83
78
|
@parallel = if !parallel || parallel.is_a?(Hash)
|
|
84
79
|
parallel
|
|
85
80
|
elsif parallel.is_a?(Integer)
|
|
@@ -95,7 +90,8 @@ module Chewy
|
|
|
95
90
|
def perform
|
|
96
91
|
ids = missing_ids | outdated_ids
|
|
97
92
|
return 0 if ids.blank?
|
|
98
|
-
|
|
93
|
+
|
|
94
|
+
@index.import(ids, parallel: @parallel) && ids.count
|
|
99
95
|
end
|
|
100
96
|
|
|
101
97
|
# Finds ids of all the objects that are not indexed yet or deleted
|
|
@@ -113,21 +109,19 @@ module Chewy
|
|
|
113
109
|
end
|
|
114
110
|
end
|
|
115
111
|
|
|
116
|
-
# If
|
|
117
|
-
#
|
|
118
|
-
# and index and returns the ids of entities which
|
|
119
|
-
# different values there.
|
|
112
|
+
# If index supports outdated sync, it compares the values of the
|
|
113
|
+
# `outdated_sync_field` for each object and document in the source
|
|
114
|
+
# and index and returns the ids of entities which differ.
|
|
120
115
|
#
|
|
121
|
-
# @see Chewy::
|
|
116
|
+
# @see Chewy::Index::Mapping::ClassMethods#supports_outdated_sync?
|
|
122
117
|
# @return [Array<String>] an array of outdated ids
|
|
123
118
|
def outdated_ids
|
|
124
|
-
return [] if source_data.blank? || index_data.blank? || !@
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
end
|
|
119
|
+
return [] if source_data.blank? || index_data.blank? || !@index.supports_outdated_sync?
|
|
120
|
+
|
|
121
|
+
@outdated_ids ||= if @parallel
|
|
122
|
+
parallel_outdated_ids
|
|
123
|
+
else
|
|
124
|
+
linear_outdated_ids
|
|
131
125
|
end
|
|
132
126
|
end
|
|
133
127
|
|
|
@@ -142,44 +136,48 @@ module Chewy
|
|
|
142
136
|
end
|
|
143
137
|
|
|
144
138
|
def source_and_index_data
|
|
145
|
-
@source_and_index_data ||=
|
|
146
|
-
if
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
[result.first.values.first, result.second.values.first]
|
|
152
|
-
else
|
|
153
|
-
[result.second.values.first, result.first.values.first]
|
|
154
|
-
end
|
|
139
|
+
@source_and_index_data ||= if @parallel
|
|
140
|
+
::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
|
|
141
|
+
result = ::Parallel.map(%i[source index], @parallel, &SOURCE_OR_INDEX_DATA_WORKER.curry[self, @index])
|
|
142
|
+
::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
|
|
143
|
+
if result.first.keys.first == :source
|
|
144
|
+
[result.first.values.first, result.second.values.first]
|
|
155
145
|
else
|
|
156
|
-
[
|
|
146
|
+
[result.second.values.first, result.first.values.first]
|
|
157
147
|
end
|
|
148
|
+
else
|
|
149
|
+
[fetch_source_data, fetch_index_data]
|
|
158
150
|
end
|
|
159
151
|
end
|
|
160
152
|
|
|
161
153
|
def fetch_source_data
|
|
162
|
-
if @
|
|
163
|
-
|
|
154
|
+
if @index.supports_outdated_sync?
|
|
155
|
+
import_fields_args = {
|
|
156
|
+
fields: [@index.outdated_sync_field],
|
|
157
|
+
batch_size: DEFAULT_SYNC_BATCH_SIZE,
|
|
158
|
+
typecast: false
|
|
159
|
+
}
|
|
160
|
+
@index.adapter.import_fields(import_fields_args).to_a.flatten(1).each do |data|
|
|
164
161
|
data[0] = data[0].to_s
|
|
165
162
|
end
|
|
166
163
|
else
|
|
167
|
-
@
|
|
164
|
+
@index.adapter.import_fields(batch_size: DEFAULT_SYNC_BATCH_SIZE, typecast: false).to_a.flatten(1).map(&:to_s)
|
|
168
165
|
end
|
|
169
166
|
end
|
|
170
167
|
|
|
171
168
|
def fetch_index_data
|
|
172
|
-
if @
|
|
173
|
-
@
|
|
169
|
+
if @index.supports_outdated_sync?
|
|
170
|
+
@index.pluck(:_id, @index.outdated_sync_field).each do |data|
|
|
174
171
|
data[0] = data[0].to_s
|
|
175
172
|
end
|
|
176
173
|
else
|
|
177
|
-
@
|
|
174
|
+
@index.pluck(:_id).map(&:to_s)
|
|
178
175
|
end
|
|
179
176
|
end
|
|
180
177
|
|
|
181
178
|
def data_ids(data)
|
|
182
|
-
return data unless @
|
|
179
|
+
return data unless @index.supports_outdated_sync?
|
|
180
|
+
|
|
183
181
|
data.map(&:first)
|
|
184
182
|
end
|
|
185
183
|
|
|
@@ -192,7 +190,12 @@ module Chewy
|
|
|
192
190
|
batches = index_data.each_slice(size)
|
|
193
191
|
|
|
194
192
|
::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
|
|
195
|
-
|
|
193
|
+
curried_outdated_ids_worker = OUTDATED_IDS_WORKER.curry[outdated_sync_field_type, source_data.to_h, @index, batches.size]
|
|
194
|
+
result = ::Parallel.map(
|
|
195
|
+
batches,
|
|
196
|
+
@parallel,
|
|
197
|
+
&curried_outdated_ids_worker
|
|
198
|
+
).flatten(1)
|
|
196
199
|
::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
|
|
197
200
|
result
|
|
198
201
|
end
|
|
@@ -203,13 +206,13 @@ module Chewy
|
|
|
203
206
|
|
|
204
207
|
def outdated_sync_field_type
|
|
205
208
|
return @outdated_sync_field_type if instance_variable_defined?(:@outdated_sync_field_type)
|
|
206
|
-
return unless @
|
|
209
|
+
return unless @index.outdated_sync_field
|
|
207
210
|
|
|
208
|
-
mappings = @
|
|
211
|
+
mappings = @index.client.indices.get_mapping(index: @index.index_name).values.first.fetch('mappings', {})
|
|
209
212
|
|
|
210
213
|
@outdated_sync_field_type = mappings
|
|
211
214
|
.fetch('properties', {})
|
|
212
|
-
.fetch(@
|
|
215
|
+
.fetch(@index.outdated_sync_field.to_s, {})['type']
|
|
213
216
|
rescue Elasticsearch::Transport::Transport::Errors::NotFound
|
|
214
217
|
nil
|
|
215
218
|
end
|
|
@@ -7,7 +7,7 @@ rescue LoadError
|
|
|
7
7
|
end
|
|
8
8
|
|
|
9
9
|
module Chewy
|
|
10
|
-
class
|
|
10
|
+
class Index
|
|
11
11
|
module Witchcraft
|
|
12
12
|
extend ActiveSupport::Concern
|
|
13
13
|
|
|
@@ -43,10 +43,10 @@ module Chewy
|
|
|
43
43
|
class Cauldron
|
|
44
44
|
attr_reader :locals
|
|
45
45
|
|
|
46
|
-
# @param
|
|
46
|
+
# @param index [Chewy::Index] index for composition
|
|
47
47
|
# @param fields [Array<Symbol>] restricts the fields for composition
|
|
48
|
-
def initialize(
|
|
49
|
-
@
|
|
48
|
+
def initialize(index, fields: [])
|
|
49
|
+
@index = index
|
|
50
50
|
@locals = []
|
|
51
51
|
@fields = fields
|
|
52
52
|
end
|
|
@@ -60,7 +60,7 @@ module Chewy
|
|
|
60
60
|
def alicorn
|
|
61
61
|
@alicorn ||= singleton_class.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
|
62
62
|
-> (locals, object0, crutches) do
|
|
63
|
-
#{composed_values(@
|
|
63
|
+
#{composed_values(@index.root, 0)}
|
|
64
64
|
end
|
|
65
65
|
RUBY
|
|
66
66
|
end
|
|
@@ -141,6 +141,7 @@ module Chewy
|
|
|
141
141
|
|
|
142
142
|
def non_proc_fields_for(parent, nesting)
|
|
143
143
|
return [] unless parent
|
|
144
|
+
|
|
144
145
|
fields = (parent.children || []).reject { |field| field.value.is_a?(Proc) }
|
|
145
146
|
|
|
146
147
|
if nesting.zero? && @fields.present?
|
|
@@ -152,6 +153,7 @@ module Chewy
|
|
|
152
153
|
|
|
153
154
|
def proc_fields_for(parent, nesting)
|
|
154
155
|
return [] unless parent
|
|
156
|
+
|
|
155
157
|
fields = (parent.children || []).select { |field| field.value.is_a?(Proc) }
|
|
156
158
|
|
|
157
159
|
if nesting.zero? && @fields.present?
|
|
@@ -173,7 +175,7 @@ module Chewy
|
|
|
173
175
|
if proc.arity.zero?
|
|
174
176
|
source = replace_self(source, :"object#{nesting}")
|
|
175
177
|
source = replace_send(source, :"object#{nesting}")
|
|
176
|
-
elsif proc.arity
|
|
178
|
+
elsif proc.arity.negative?
|
|
177
179
|
raise "Splat arguments are unsupported by witchcraft:\n`#{proc.source}"
|
|
178
180
|
else
|
|
179
181
|
(nesting + 1).times do |n|
|
|
@@ -192,6 +194,7 @@ module Chewy
|
|
|
192
194
|
|
|
193
195
|
def exctract_lambdas(node)
|
|
194
196
|
return unless node.is_a?(Parser::AST::Node)
|
|
197
|
+
|
|
195
198
|
if node.type == :block && node.children[0].type == :send && node.children[0].to_a == [nil, :lambda]
|
|
196
199
|
[node.children[2]]
|
|
197
200
|
else
|
|
@@ -214,7 +217,7 @@ module Chewy
|
|
|
214
217
|
def replace_send(node, variable)
|
|
215
218
|
if node.is_a?(Parser::AST::Node)
|
|
216
219
|
if node.type == :send && node.children[0].nil?
|
|
217
|
-
node.updated(nil, [Parser::AST::Node.new(:lvar, [variable]), *node.children[1
|
|
220
|
+
node.updated(nil, [Parser::AST::Node.new(:lvar, [variable]), *node.children[1..]])
|
|
218
221
|
else
|
|
219
222
|
node.updated(nil, node.children.map { |child| replace_send(child, variable) })
|
|
220
223
|
end
|
|
@@ -253,6 +256,7 @@ module Chewy
|
|
|
253
256
|
|
|
254
257
|
def binding_variable_list(node)
|
|
255
258
|
return unless node.is_a?(Parser::AST::Node)
|
|
259
|
+
|
|
256
260
|
if node.type == :send && node.children[0].nil?
|
|
257
261
|
node.children[1]
|
|
258
262
|
else
|