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.
Files changed (131) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +58 -0
  3. data/.rubocop.yml +13 -8
  4. data/.rubocop_todo.yml +110 -22
  5. data/CHANGELOG.md +53 -0
  6. data/Gemfile +0 -7
  7. data/Guardfile +3 -1
  8. data/README.md +282 -245
  9. data/chewy.gemspec +3 -5
  10. data/gemfiles/rails.5.2.activerecord.gemfile +8 -14
  11. data/gemfiles/rails.6.0.activerecord.gemfile +8 -14
  12. data/gemfiles/rails.6.1.activerecord.gemfile +8 -14
  13. data/lib/chewy.rb +21 -75
  14. data/lib/chewy/config.rb +40 -40
  15. data/lib/chewy/errors.rb +0 -12
  16. data/lib/chewy/fields/base.rb +11 -1
  17. data/lib/chewy/fields/root.rb +3 -4
  18. data/lib/chewy/index.rb +46 -87
  19. data/lib/chewy/index/actions.rb +51 -32
  20. data/lib/chewy/{type → index}/adapter/active_record.rb +12 -3
  21. data/lib/chewy/{type → index}/adapter/base.rb +2 -3
  22. data/lib/chewy/{type → index}/adapter/object.rb +27 -31
  23. data/lib/chewy/{type → index}/adapter/orm.rb +11 -14
  24. data/lib/chewy/{type → index}/crutch.rb +5 -5
  25. data/lib/chewy/{type → index}/import.rb +36 -27
  26. data/lib/chewy/{type → index}/import/bulk_builder.rb +15 -13
  27. data/lib/chewy/{type → index}/import/bulk_request.rb +6 -6
  28. data/lib/chewy/{type → index}/import/journal_builder.rb +10 -10
  29. data/lib/chewy/{type → index}/import/routine.rb +15 -14
  30. data/lib/chewy/{type → index}/mapping.rb +26 -31
  31. data/lib/chewy/{type → index}/observe.rb +9 -19
  32. data/lib/chewy/index/specification.rb +1 -0
  33. data/lib/chewy/{type → index}/syncer.rb +60 -57
  34. data/lib/chewy/{type → index}/witchcraft.rb +11 -7
  35. data/lib/chewy/{type → index}/wrapper.rb +2 -2
  36. data/lib/chewy/journal.rb +8 -8
  37. data/lib/chewy/minitest/helpers.rb +9 -13
  38. data/lib/chewy/minitest/search_index_receiver.rb +22 -26
  39. data/lib/chewy/railtie.rb +4 -2
  40. data/lib/chewy/rake_helper.rb +82 -107
  41. data/lib/chewy/rspec/update_index.rb +47 -43
  42. data/lib/chewy/search.rb +4 -17
  43. data/lib/chewy/search/loader.rb +18 -30
  44. data/lib/chewy/search/parameters.rb +4 -2
  45. data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
  46. data/lib/chewy/search/parameters/source.rb +5 -1
  47. data/lib/chewy/search/query_proxy.rb +9 -2
  48. data/lib/chewy/search/request.rb +82 -86
  49. data/lib/chewy/search/response.rb +4 -4
  50. data/lib/chewy/search/scoping.rb +6 -7
  51. data/lib/chewy/search/scrolling.rb +11 -11
  52. data/lib/chewy/stash.rb +14 -22
  53. data/lib/chewy/strategy.rb +3 -19
  54. data/lib/chewy/strategy/sidekiq.rb +1 -0
  55. data/lib/chewy/version.rb +1 -1
  56. data/lib/generators/chewy/install_generator.rb +1 -1
  57. data/lib/tasks/chewy.rake +10 -22
  58. data/migration_guide.md +14 -0
  59. data/spec/chewy/config_spec.rb +14 -39
  60. data/spec/chewy/fields/base_spec.rb +412 -148
  61. data/spec/chewy/fields/root_spec.rb +16 -24
  62. data/spec/chewy/fields/time_fields_spec.rb +5 -5
  63. data/spec/chewy/index/actions_spec.rb +270 -24
  64. data/spec/chewy/{type → index}/adapter/active_record_spec.rb +68 -40
  65. data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
  66. data/spec/chewy/{type → index}/import/bulk_builder_spec.rb +23 -31
  67. data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -6
  68. data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -15
  69. data/spec/chewy/{type → index}/import/routine_spec.rb +16 -16
  70. data/spec/chewy/{type → index}/import_spec.rb +102 -98
  71. data/spec/chewy/{type → index}/mapping_spec.rb +46 -54
  72. data/spec/chewy/index/observe_spec.rb +116 -0
  73. data/spec/chewy/index/settings_spec.rb +3 -1
  74. data/spec/chewy/index/specification_spec.rb +7 -17
  75. data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
  76. data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
  77. data/spec/chewy/index/wrapper_spec.rb +100 -0
  78. data/spec/chewy/index_spec.rb +59 -102
  79. data/spec/chewy/journal_spec.rb +9 -22
  80. data/spec/chewy/minitest/helpers_spec.rb +13 -15
  81. data/spec/chewy/minitest/search_index_receiver_spec.rb +22 -26
  82. data/spec/chewy/multi_search_spec.rb +4 -5
  83. data/spec/chewy/rake_helper_spec.rb +145 -55
  84. data/spec/chewy/rspec/update_index_spec.rb +74 -71
  85. data/spec/chewy/search/loader_spec.rb +19 -37
  86. data/spec/chewy/search/pagination/kaminari_examples.rb +3 -5
  87. data/spec/chewy/search/pagination/kaminari_spec.rb +1 -1
  88. data/spec/chewy/search/parameters/indices_spec.rb +2 -8
  89. data/spec/chewy/search/parameters/order_spec.rb +1 -1
  90. data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
  91. data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
  92. data/spec/chewy/search/parameters/source_spec.rb +8 -2
  93. data/spec/chewy/search/parameters_spec.rb +12 -3
  94. data/spec/chewy/search/query_proxy_spec.rb +68 -17
  95. data/spec/chewy/search/request_spec.rb +222 -74
  96. data/spec/chewy/search/response_spec.rb +12 -12
  97. data/spec/chewy/search/scrolling_spec.rb +7 -9
  98. data/spec/chewy/search_spec.rb +32 -35
  99. data/spec/chewy/stash_spec.rb +9 -21
  100. data/spec/chewy/strategy/active_job_spec.rb +8 -8
  101. data/spec/chewy/strategy/atomic_spec.rb +9 -10
  102. data/spec/chewy/strategy/sidekiq_spec.rb +8 -8
  103. data/spec/chewy/strategy_spec.rb +19 -15
  104. data/spec/chewy_spec.rb +14 -100
  105. data/spec/spec_helper.rb +2 -21
  106. data/spec/support/active_record.rb +15 -5
  107. metadata +44 -103
  108. data/.circleci/config.yml +0 -214
  109. data/Appraisals +0 -81
  110. data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
  111. data/gemfiles/sequel.4.45.gemfile +0 -11
  112. data/lib/chewy/search/pagination/will_paginate.rb +0 -43
  113. data/lib/chewy/strategy/resque.rb +0 -27
  114. data/lib/chewy/strategy/shoryuken.rb +0 -40
  115. data/lib/chewy/type.rb +0 -120
  116. data/lib/chewy/type/actions.rb +0 -43
  117. data/lib/chewy/type/adapter/mongoid.rb +0 -67
  118. data/lib/chewy/type/adapter/sequel.rb +0 -93
  119. data/lib/sequel/plugins/chewy_observe.rb +0 -63
  120. data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
  121. data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
  122. data/spec/chewy/strategy/resque_spec.rb +0 -46
  123. data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
  124. data/spec/chewy/type/actions_spec.rb +0 -50
  125. data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
  126. data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
  127. data/spec/chewy/type/observe_spec.rb +0 -137
  128. data/spec/chewy/type/wrapper_spec.rb +0 -100
  129. data/spec/chewy/type_spec.rb +0 -55
  130. data/spec/support/mongoid.rb +0 -93
  131. data/spec/support/sequel.rb +0 -80
@@ -1,5 +1,5 @@
1
1
  module Chewy
2
- class Type
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 type
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
- # define_type User do
23
- # # root object defined implicitly and optionless for current type
24
- # field :full_name, type: 'keyword'
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
- # define_type Car do
30
- # # explicit root definition with additional options
31
- # root dynamic_date_formats: ['yyyy-MM-dd'] do
32
- # field :model_name, type: 'keyword'
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(type_name, **Chewy.default_root_options.merge(options))
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 current type
42
+ # Defines mapping field for index
45
43
  #
46
44
  # @example
47
45
  # class UsersIndex < Chewy::Index
48
- # define_type User do
49
- # # passing all the options to field definition:
50
- # field :full_name, analyzer: 'special'
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
- # define_type User do
142
- # field :posts do
143
- # field :rating
144
- # end
145
- #
146
- # agg :avg_rating do
147
- # { avg: { field: 'posts.rating' } }
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
- # define_type Car do
161
- # template 'model.*', type: 'text', analyzer: 'special'
162
- # field 'model', type: 'object' # here we can put { de: 'Der Mercedes', en: 'Mercedes' }
163
- # # and template will be applyed to this field
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 the optionsl second argument
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 Type
2
+ class Index
3
3
  module Observe
4
4
  extend ActiveSupport::Concern
5
5
 
6
6
  module Helpers
7
- def update_proc(type_name, *args, &block)
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 type_name.is_a?(Proc)
13
- if type_name.arity.zero?
14
- instance_exec(&type_name)
12
+ reference = if index_name.is_a?(Proc)
13
+ if index_name.arity.zero?
14
+ instance_exec(&index_name)
15
15
  else
16
- type_name.call(self)
16
+ index_name.call(self)
17
17
  end
18
18
  else
19
- type_name
19
+ index_name
20
20
  end
21
21
 
22
- type = Chewy.derive_type(reference)
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
- type.update_index(backreference, options)
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)
@@ -36,6 +36,7 @@ module Chewy
36
36
  filter = {ids: {values: [@index.derivable_name]}}
37
37
  document = Chewy::Stash::Specification.filter(filter).first
38
38
  return {} unless document
39
+
39
40
  JSON.load(Base64.decode64(document.specification)) # rubocop:disable Security/JSONLoad
40
41
  end
41
42
 
@@ -1,5 +1,5 @@
1
1
  module Chewy
2
- class Type
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::Type::Adapter::Base#import_fields}, in case when the Object
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 surce and
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::Type::Actions::ClassMethods#sync
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, type, total, index_data|
32
- ::Process.setproctitle("chewy [#{type}]: sync outdated calculation (#{::Parallel.worker_number + 1}/#{total})") if type
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::Type::Syncer.dates_equal(typecast_date(source_data_hash[id]), Time.iso8601(index_sync_value))
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, type, kind|
46
- ::Process.setproctitle("chewy [#{type}]: sync fetching data (#{kind})")
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
- date = "#{match[1]}-#{match[2]}-#{match[3]}T#{match[4]}:#{match[5]}:#{match[6]}.#{format('%06d', microsec)}+00:00"
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
- # In ActiveSupport ~> 4.0 json dumpled times without any
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(type, parallel: nil)
82
- @type = type
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
- @type.import(ids, parallel: @parallel) && ids.count
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 type supports outdated sync, it compares for the values of the
117
- # type `outdated_sync_field` for each object and document in the source
118
- # and index and returns the ids of entities which which are having
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::Type::Mapping::ClassMethods#supports_outdated_sync?
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? || !@type.supports_outdated_sync?
125
- @outdated_ids ||= begin
126
- if @parallel
127
- parallel_outdated_ids
128
- else
129
- linear_outdated_ids
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 ||= begin
146
- if @parallel
147
- ::ActiveRecord::Base.connection.close if defined?(::ActiveRecord::Base)
148
- result = ::Parallel.map(%i[source index], @parallel, &SOURCE_OR_INDEX_DATA_WORKER.curry[self, @type])
149
- ::ActiveRecord::Base.connection.reconnect! if defined?(::ActiveRecord::Base)
150
- if result.first.keys.first == :source
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
- [fetch_source_data, fetch_index_data]
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 @type.supports_outdated_sync?
163
- @type.adapter.import_fields(fields: [@type.outdated_sync_field], batch_size: DEFAULT_SYNC_BATCH_SIZE, typecast: false).to_a.flatten(1).each do |data|
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
- @type.adapter.import_fields(batch_size: DEFAULT_SYNC_BATCH_SIZE, typecast: false).to_a.flatten(1).map(&:to_s)
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 @type.supports_outdated_sync?
173
- @type.pluck(:_id, @type.outdated_sync_field).each do |data|
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
- @type.pluck(:_id).map(&:to_s)
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 @type.supports_outdated_sync?
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
- result = ::Parallel.map(batches, @parallel, &OUTDATED_IDS_WORKER.curry[outdated_sync_field_type, source_data.to_h, @type, batches.size]).flatten(1)
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 @type.outdated_sync_field
209
+ return unless @index.outdated_sync_field
207
210
 
208
- mappings = @type.client.indices.get_mapping(index: @type.index_name).values.first.fetch('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(@type.outdated_sync_field.to_s, {})['type']
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 Type
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 type [Chewy::Type] type for composition
46
+ # @param index [Chewy::Index] index for composition
47
47
  # @param fields [Array<Symbol>] restricts the fields for composition
48
- def initialize(type, fields: [])
49
- @type = type
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(@type.root, 0)}
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 < 0
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..-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