chewy 7.1.0 → 7.2.0

Sign up to get free protection for your applications and to get access to all the features.
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 Wrapper
4
4
  extend ActiveSupport::Concern
5
5
 
@@ -28,7 +28,7 @@ module Chewy
28
28
  def ==(other)
29
29
  return true if super
30
30
 
31
- if other.is_a?(Chewy::Type)
31
+ if other.is_a?(Chewy::Index)
32
32
  self.class == other.class && (respond_to?(:id) ? id == other.id : attributes == other.attributes)
33
33
  elsif other.respond_to?(:id)
34
34
  self.class.adapter.target.is_a?(Class) &&
data/lib/chewy/journal.rb CHANGED
@@ -2,18 +2,18 @@ module Chewy
2
2
  # A class to perform journal-related actions for the specified indexes/types.
3
3
  #
4
4
  # @example
5
- # journal = Chewy::Journal.new('places#city', UsersIndex)
5
+ # journal = Chewy::Journal.new('places', UsersIndex)
6
6
  # journal.apply(20.minutes.ago)
7
7
  # journal.clean
8
8
  #
9
9
  class Journal
10
- # @param only [Array<String, Chewy::Index, Chewy::Type>] indexes/types or even string references to perform actions on
10
+ # @param only [Array<String, Chewy::Index>] indexes or string references to perform actions on
11
11
  def initialize(*only)
12
12
  @only = only
13
13
  end
14
14
 
15
15
  # Applies all changes that were done since the specified time to the
16
- # specified indexes/types.
16
+ # specified indexes.
17
17
  #
18
18
  # @param since_time [Time, DateTime] timestamp from which changes will be applied
19
19
  # @param retries [Integer] maximum number of attempts to make journal empty, 10 by default
@@ -27,8 +27,8 @@ module Chewy
27
27
  count += entries.size
28
28
  groups = reference_groups(entries)
29
29
  ActiveSupport::Notifications.instrument 'apply_journal.chewy', stage: stage, groups: groups
30
- groups.each do |type, references|
31
- type.import(references, import_options.merge(journal: false))
30
+ groups.each do |index, references|
31
+ index.import(references, import_options.merge(journal: false))
32
32
  end
33
33
  stage += 1
34
34
  since_time = entries.map(&:created_at).max
@@ -47,9 +47,9 @@ module Chewy
47
47
  private
48
48
 
49
49
  def reference_groups(entries)
50
- entries.group_by(&:type).map do |type, grouped_entries|
51
- [type, grouped_entries.map(&:references).inject(:|)]
52
- end.to_h
50
+ entries.group_by(&:index_name)
51
+ .transform_keys { |index_name| Chewy.derive_name(index_name) }
52
+ .transform_values { |grouped_entries| grouped_entries.map(&:references).inject(:|) }
53
53
  end
54
54
  end
55
55
  end
@@ -6,7 +6,7 @@ module Chewy
6
6
  extend ActiveSupport::Concern
7
7
 
8
8
  # Assert that an index *changes* during a block.
9
- # @param index [Chewy::Type] the index / type to watch, eg EntitiesIndex::Entity.
9
+ # @param index [Chewy::Index] the index to watch, eg EntitiesIndex.
10
10
  # @param strategy [Symbol] the Chewy strategy to use around the block. See Chewy docs.
11
11
  # @param bypass_actual_index [true, false]
12
12
  # True to preempt the http call to Elastic, false otherwise.
@@ -14,11 +14,11 @@ module Chewy
14
14
  #
15
15
  # @return [SearchIndexReceiver] for optional further assertions on the nature of the index changes.
16
16
  #
17
- def assert_indexes(index, strategy: :atomic, bypass_actual_index: true)
18
- type = Chewy.derive_type index
17
+ def assert_indexes(index, strategy: :atomic, bypass_actual_index: true, &block)
18
+ index_class = Chewy.derive_name index
19
19
  receiver = SearchIndexReceiver.new
20
20
 
21
- bulk_method = type.method :bulk
21
+ bulk_method = index_class.method :bulk
22
22
  # Manually mocking #bulk because we need to properly capture `self`
23
23
  bulk_mock = lambda do |*bulk_args|
24
24
  receiver.catch bulk_args, self
@@ -28,13 +28,11 @@ module Chewy
28
28
  {}
29
29
  end
30
30
 
31
- type.define_singleton_method :bulk, bulk_mock
31
+ index_class.define_singleton_method :bulk, bulk_mock
32
32
 
33
- Chewy.strategy(strategy) do
34
- yield
35
- end
33
+ Chewy.strategy(strategy, &block)
36
34
 
37
- type.define_singleton_method :bulk, bulk_method
35
+ index_class.define_singleton_method :bulk, bulk_method
38
36
 
39
37
  assert_includes receiver.updated_indexes, index, "Expected #{index} to be updated but it wasn't"
40
38
 
@@ -44,10 +42,8 @@ module Chewy
44
42
  # Run indexing for the database changes during the block provided.
45
43
  # By default, indexing is run at the end of the block.
46
44
  # @param strategy [Symbol] the Chewy index update strategy see Chewy docs.
47
- def run_indexing(strategy: :atomic)
48
- Chewy.strategy strategy do
49
- yield
50
- end
45
+ def run_indexing(strategy: :atomic, &block)
46
+ Chewy.strategy strategy, &block
51
47
  end
52
48
 
53
49
  module ClassMethods
@@ -1,80 +1,76 @@
1
1
  # Test helper class to provide minitest hooks for Chewy::Index testing.
2
2
  #
3
3
  # @note Intended to be used in conjunction with a test helper which mocks over the #bulk
4
- # method on a {Chewy::Type} class. (See SearchTestHelper)
4
+ # method on a {Chewy::Index} class. (See {Chewy::Minitest::Helpers})
5
5
  #
6
- # The class will capture the data from the *param on the Chewy::Type.bulk method and
6
+ # The class will capture the data from the *param on the Chewy::Index.bulk method and
7
7
  # aggregate the data for test analysis.
8
8
  class SearchIndexReceiver
9
9
  def initialize
10
10
  @mutations = {}
11
11
  end
12
12
 
13
- # @param bulk_params [Hash] the bulk_params that should be sent to the Chewy::Type.bulk method.
14
- # @param type [Chewy::Type] the type executing this query.
15
- def catch(bulk_params, type)
13
+ # @param bulk_params [Hash] the bulk_params that should be sent to the Chewy::Index.bulk method.
14
+ # @param index [Chewy::Index] the index executing this query.
15
+ def catch(bulk_params, index)
16
16
  Array.wrap(bulk_params).map { |y| y[:body] }.flatten.each do |update|
17
17
  if update[:delete]
18
- mutation_for(type).deletes << update[:delete][:_id]
18
+ mutation_for(index).deletes << update[:delete][:_id]
19
19
  elsif update[:index]
20
- mutation_for(type).indexes << update[:index]
20
+ mutation_for(index).indexes << update[:index]
21
21
  end
22
22
  end
23
23
  end
24
24
 
25
- # @param index [Chewy::Index] return only index requests to the specified {Chewy::Type} index.
25
+ # @param index [Chewy::Index] return only index requests to the specified {Chewy::Index} index.
26
26
  # @return [Hash] the index changes captured by the mock.
27
27
  def indexes_for(index = nil)
28
28
  if index
29
29
  mutation_for(index).indexes
30
30
  else
31
- Hash[
32
- @mutations.map { |a, b| [a, b.indexes] }
33
- ]
31
+ @mutations.transform_values(&:indexes)
34
32
  end
35
33
  end
36
34
  alias_method :indexes, :indexes_for
37
35
 
38
- # @param index [Chewy::Index] return only delete requests to the specified {Chewy::Type} index.
36
+ # @param index [Chewy::Index] return only delete requests to the specified {Chewy::Index} index.
39
37
  # @return [Hash] the index deletes captured by the mock.
40
38
  def deletes_for(index = nil)
41
39
  if index
42
40
  mutation_for(index).deletes
43
41
  else
44
- Hash[
45
- @mutations.map { |a, b| [a, b.deletes] }
46
- ]
42
+ @mutations.transform_values(&:deletes)
47
43
  end
48
44
  end
49
45
  alias_method :deletes, :deletes_for
50
46
 
51
47
  # Check to see if a given object has been indexed.
52
48
  # @param obj [#id] obj the object to look for.
53
- # @param type [Chewy::Type] what type the object should be indexed as.
49
+ # @param index [Chewy::Index] what index the object should be indexed in.
54
50
  # @return [true, false] if the object was indexed.
55
- def indexed?(obj, type)
56
- indexes_for(type).map { |i| i[:_id] }.include? obj.id
51
+ def indexed?(obj, index)
52
+ indexes_for(index).map { |i| i[:_id] }.include? obj.id
57
53
  end
58
54
 
59
55
  # Check to see if a given object has been deleted.
60
56
  # @param obj [#id] obj the object to look for.
61
- # @param type [Chewy::Type] what type the object should have been deleted from.
57
+ # @param index [Chewy::Index] what index the object should have been deleted from.
62
58
  # @return [true, false] if the object was deleted.
63
- def deleted?(obj, type)
64
- deletes_for(type).include? obj.id
59
+ def deleted?(obj, index)
60
+ deletes_for(index).include? obj.id
65
61
  end
66
62
 
67
- # @return [Array<Chewy::Type>] a list of types indexes changed.
63
+ # @return [Array<Chewy::Index>] a list of indexes changed.
68
64
  def updated_indexes
69
65
  @mutations.keys
70
66
  end
71
67
 
72
68
  private
73
69
 
74
- # Get the mutation object for a given type.
75
- # @param type [Chewy::Type] the index type to fetch.
70
+ # Get the mutation object for a given index.
71
+ # @param index [Chewy::Index] the index to fetch.
76
72
  # @return [#indexes, #deletes] an object with a list of indexes and a list of deletes.
77
- def mutation_for(type)
78
- @mutations[type] ||= OpenStruct.new(indexes: [], deletes: [])
73
+ def mutation_for(index)
74
+ @mutations[index] ||= OpenStruct.new(indexes: [], deletes: [])
79
75
  end
80
76
  end
data/lib/chewy/railtie.rb CHANGED
@@ -14,7 +14,9 @@ module Chewy
14
14
  if Rails.application.config.respond_to?(:assets) && env['PATH_INFO'].start_with?(Rails.application.config.assets.prefix)
15
15
  @app.call(env)
16
16
  else
17
- Chewy.logger.info("Chewy request strategy is `#{Chewy.request_strategy}`") if Chewy.logger && @request_strategy != Chewy.request_strategy
17
+ if Chewy.logger && @request_strategy != Chewy.request_strategy
18
+ Chewy.logger.info("Chewy request strategy is `#{Chewy.request_strategy}`")
19
+ end
18
20
  @request_strategy = Chewy.request_strategy
19
21
  Chewy.strategy(Chewy.request_strategy) { @app.call(env) }
20
22
  end
@@ -35,7 +37,7 @@ module Chewy
35
37
  if app.sandbox?
36
38
  Chewy.strategy(:bypass)
37
39
  else
38
- Chewy.strategy(:urgent)
40
+ Chewy.strategy(Chewy.console_strategy)
39
41
  end
40
42
  puts "Chewy console strategy is `#{Chewy.strategy.current.name}`"
41
43
  end
@@ -3,14 +3,12 @@ module Chewy
3
3
  IMPORT_CALLBACK = lambda do |output, _name, start, finish, _id, payload|
4
4
  duration = (finish - start).ceil
5
5
  stats = payload.fetch(:import, {}).map { |key, count| "#{key} #{count}" }.join(', ')
6
- output.puts " Imported #{payload[:type]} in #{human_duration(duration)}, stats: #{stats}"
7
- if payload[:errors]
8
- payload[:errors].each do |action, errors|
9
- output.puts " #{action.to_s.humanize} errors:"
10
- errors.each do |error, documents|
11
- output.puts " `#{error}`"
12
- output.puts " on #{documents.count} documents: #{documents}"
13
- end
6
+ output.puts " Imported #{payload[:index]} in #{human_duration(duration)}, stats: #{stats}"
7
+ payload[:errors]&.each do |action, errors|
8
+ output.puts " #{action.to_s.humanize} errors:"
9
+ errors.each do |error, documents|
10
+ output.puts " `#{error}`"
11
+ output.puts " on #{documents.count} documents: #{documents}"
14
12
  end
15
13
  end
16
14
  end
@@ -36,7 +34,7 @@ module Chewy
36
34
  # @param parallel [true, Integer, Hash] any acceptable parallel options for import
37
35
  # @param output [IO] output io for logging
38
36
  # @return [Array<Chewy::Index>] indexes that were reset
39
- def reset(only: nil, except: nil, parallel: nil, output: STDOUT)
37
+ def reset(only: nil, except: nil, parallel: nil, output: $stdout)
40
38
  subscribed_task_stats(output) do
41
39
  indexes_from(only: only, except: except).each do |index|
42
40
  reset_one(index, output, parallel: parallel)
@@ -59,7 +57,7 @@ module Chewy
59
57
  # @param parallel [true, Integer, Hash] any acceptable parallel options for import
60
58
  # @param output [IO] output io for logging
61
59
  # @return [Array<Chewy::Index>] indexes that were actually reset
62
- def upgrade(only: nil, except: nil, parallel: nil, output: STDOUT)
60
+ def upgrade(only: nil, except: nil, parallel: nil, output: $stdout)
63
61
  subscribed_task_stats(output) do
64
62
  indexes = indexes_from(only: only, except: except)
65
63
 
@@ -87,23 +85,21 @@ module Chewy
87
85
  #
88
86
  # @example
89
87
  # Chewy::RakeHelper.update # updates everything
90
- # Chewy::RakeHelper.update(only: 'places') # updates only PlacesIndex::City and PlacesIndex::Country
91
- # Chewy::RakeHelper.update(only: 'places#city') # updates PlacesIndex::City only
92
- # Chewy::RakeHelper.update(except: PlacesIndex::Country) # updates everything, but PlacesIndex::Country
93
- # Chewy::RakeHelper.update(only: 'places', except: 'places#country') # updates PlacesIndex::City only
88
+ # Chewy::RakeHelper.update(only: 'places') # updates only PlacesIndex
89
+ # Chewy::RakeHelper.update(except: PlacesIndex) # updates everything, but PlacesIndex
94
90
  #
95
- # @param only [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to update; if nothing is passed - uses all the types defined in the app
96
- # @param except [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to exclude from processing
91
+ # @param only [Array<Chewy::Index, String>, Chewy::Index, String] indexes to update; if nothing is passed - uses all the indexes defined in the app
92
+ # @param except [Array<Chewy::Index, String>, Chewy::Index, String] indexes to exclude from processing
97
93
  # @param parallel [true, Integer, Hash] any acceptable parallel options for import
98
94
  # @param output [IO] output io for logging
99
- # @return [Array<Chewy::Type>] types that were actually updated
100
- def update(only: nil, except: nil, parallel: nil, output: STDOUT)
95
+ # @return [Array<Chewy::Index>] indexes that were actually updated
96
+ def update(only: nil, except: nil, parallel: nil, output: $stdout)
101
97
  subscribed_task_stats(output) do
102
- types_from(only: only, except: except).group_by(&:index).each_with_object([]) do |(index, types), update_types|
98
+ indexes_from(only: only, except: except).each_with_object([]) do |index, updated_indexes|
103
99
  if index.exists?
104
100
  output.puts "Updating #{index}"
105
- types.each { |type| type.import(parallel: parallel) }
106
- update_types.concat(types)
101
+ index.import(parallel: parallel)
102
+ updated_indexes.push(index)
107
103
  else
108
104
  output.puts "Skipping #{index}, it does not exists (use rake chewy:reset[#{index.derivable_name}] to create and update it)"
109
105
  end
@@ -115,31 +111,29 @@ module Chewy
115
111
  #
116
112
  # @example
117
113
  # Chewy::RakeHelper.sync # synchronizes everything
118
- # Chewy::RakeHelper.sync(only: 'places') # synchronizes only PlacesIndex::City and PlacesIndex::Country
119
- # Chewy::RakeHelper.sync(only: 'places#city') # synchronizes PlacesIndex::City only
120
- # Chewy::RakeHelper.sync(except: PlacesIndex::Country) # synchronizes everything, but PlacesIndex::Country
121
- # Chewy::RakeHelper.sync(only: 'places', except: 'places#country') # synchronizes PlacesIndex::City only
114
+ # Chewy::RakeHelper.sync(only: 'places') # synchronizes only PlacesIndex
115
+ # Chewy::RakeHelper.sync(except: PlacesIndex) # synchronizes everything, but PlacesIndex
122
116
  #
123
- # @param only [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to synchronize; if nothing is passed - uses all the types defined in the app
124
- # @param except [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to exclude from processing
117
+ # @param only [Array<Chewy::Index, String>, Chewy::Index, String] indexes to synchronize; if nothing is passed - uses all the indexes defined in the app
118
+ # @param except [Array<Chewy::Index, String>, Chewy::Index, String] indexes to exclude from processing
125
119
  # @param parallel [true, Integer, Hash] any acceptable parallel options for sync
126
120
  # @param output [IO] output io for logging
127
- # @return [Array<Chewy::Type>] types that were actually updated
128
- def sync(only: nil, except: nil, parallel: nil, output: STDOUT)
121
+ # @return [Array<Chewy::Index>] indexes that were actually updated
122
+ def sync(only: nil, except: nil, parallel: nil, output: $stdout)
129
123
  subscribed_task_stats(output) do
130
- types_from(only: only, except: except).each_with_object([]) do |type, synced_types|
131
- output.puts "Synchronizing #{type}"
132
- output.puts " #{type} doesn't support outdated synchronization" unless type.supports_outdated_sync?
124
+ indexes_from(only: only, except: except).each_with_object([]) do |index, synced_indexes|
125
+ output.puts "Synchronizing #{index}"
126
+ output.puts " #{index} doesn't support outdated synchronization" unless index.supports_outdated_sync?
133
127
  time = Time.now
134
- sync_result = type.sync(parallel: parallel)
128
+ sync_result = index.sync(parallel: parallel)
135
129
  if !sync_result
136
- output.puts " Something went wrong with the #{type} synchronization"
137
- elsif sync_result[:count] > 0
130
+ output.puts " Something went wrong with the #{index} synchronization"
131
+ elsif (sync_result[:count]).positive?
138
132
  output.puts " Missing documents: #{sync_result[:missing]}" if sync_result[:missing].present?
139
133
  output.puts " Outdated documents: #{sync_result[:outdated]}" if sync_result[:outdated].present?
140
- synced_types.push(type)
134
+ synced_indexes.push(index)
141
135
  else
142
- output.puts " Skipping #{type}, up to date"
136
+ output.puts " Skipping #{index}, up to date"
143
137
  end
144
138
  output.puts " Took #{human_duration(Time.now - time)}"
145
139
  end
@@ -147,49 +141,46 @@ module Chewy
147
141
  end
148
142
 
149
143
  # Applies changes that were done after the specified time for the
150
- # specified indexes/types or all of them.
144
+ # specified indexes or all of them.
151
145
  #
152
146
  # @example
153
147
  # Chewy::RakeHelper.journal_apply(time: 1.minute.ago) # applies entries created for the last minute
154
- # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, only: 'places') # applies only PlacesIndex::City and PlacesIndex::Country entries reated for the last minute
155
- # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, only: 'places#city') # applies PlacesIndex::City entries reated for the last minute only
156
- # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, except: PlacesIndex::Country) # applies everything, but PlacesIndex::Country entries reated for the last minute
157
- # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, only: 'places', except: 'places#country') # applies PlacesIndex::City entries reated for the last minute only
148
+ # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, only: 'places') # applies only PlacesIndex entries created for the last minute
149
+ # Chewy::RakeHelper.journal_apply(time: 1.minute.ago, except: PlacesIndex) # applies everything, but PlacesIndex, entries created for the last minute
158
150
  #
159
151
  # @param time [Time, DateTime] use only journal entries created after this time
160
- # @param only [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to synchronize; if nothing is passed - uses all the types defined in the app
161
- # @param except [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to exclude from processing
152
+ # @param only [Array<Chewy::Index, String>, Chewy::Index, String] indexes to synchronize; if nothing is passed - uses all the indexes defined in the app
153
+ # @param except [Array<Chewy::Index, String>, Chewy::Index, String] indexes to exclude from processing
162
154
  # @param output [IO] output io for logging
163
- # @return [Array<Chewy::Type>] types that were actually updated
164
- def journal_apply(time: nil, only: nil, except: nil, output: STDOUT)
155
+ # @return [Array<Chewy::Index>] indexes that were actually updated
156
+ def journal_apply(time: nil, only: nil, except: nil, output: $stdout)
165
157
  raise ArgumentError, 'Please specify the time to start with' unless time
158
+
166
159
  subscribed_task_stats(output) do
167
160
  output.puts "Applying journal entries created after #{time}"
168
- count = Chewy::Journal.new(types_from(only: only, except: except)).apply(time)
161
+ count = Chewy::Journal.new(indexes_from(only: only, except: except)).apply(time)
169
162
  output.puts 'No journal entries were created after the specified time' if count.zero?
170
163
  end
171
164
  end
172
165
 
173
166
  # Removes journal records created before the specified timestamp for
174
- # the specified indexes/types or all of them.
167
+ # the specified indexes or all of them.
175
168
  #
176
169
  # @example
177
170
  # Chewy::RakeHelper.journal_clean # cleans everything
178
171
  # Chewy::RakeHelper.journal_clean(time: 1.minute.ago) # leaves only entries created for the last minute
179
- # Chewy::RakeHelper.journal_clean(only: 'places') # cleans only PlacesIndex::City and PlacesIndex::Country entries
180
- # Chewy::RakeHelper.journal_clean(only: 'places#city') # cleans PlacesIndex::City entries only
181
- # Chewy::RakeHelper.journal_clean(except: PlacesIndex::Country) # cleans everything, but PlacesIndex::Country entries
182
- # Chewy::RakeHelper.journal_clean(only: 'places', except: 'places#country') # cleans PlacesIndex::City entries only
172
+ # Chewy::RakeHelper.journal_clean(only: 'places') # cleans only PlacesIndex entries
173
+ # Chewy::RakeHelper.journal_clean(except: PlacesIndex) # cleans everything, but PlacesIndex entries
183
174
  #
184
175
  # @param time [Time, DateTime] clean all the journal entries created before this time
185
- # @param only [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to synchronize; if nothing is passed - uses all the types defined in the app
186
- # @param except [Array<Chewy::Index, Chewy::Type, String>, Chewy::Index, Chewy::Type, String] indexes or types to exclude from processing
176
+ # @param only [Array<Chewy::Index, String>, Chewy::Index, String] indexes to synchronize; if nothing is passed - uses all the indexes defined in the app
177
+ # @param except [Array<Chewy::Index, String>, Chewy::Index, String] indexes to exclude from processing
187
178
  # @param output [IO] output io for logging
188
- # @return [Array<Chewy::Type>] types that were actually updated
189
- def journal_clean(time: nil, only: nil, except: nil, output: STDOUT)
179
+ # @return [Array<Chewy::Index>] indexes that were actually updated
180
+ def journal_clean(time: nil, only: nil, except: nil, output: $stdout)
190
181
  subscribed_task_stats(output) do
191
182
  output.puts "Cleaning journal entries created before #{time}" if time
192
- response = Chewy::Journal.new(types_from(only: only, except: except)).clean(time)
183
+ response = Chewy::Journal.new(indexes_from(only: only, except: except)).clean(time)
193
184
  count = response['deleted'] || response['_indices']['_all']['deleted']
194
185
  output.puts "Cleaned up #{count} journal entries"
195
186
  end
@@ -204,45 +195,53 @@ module Chewy
204
195
  Chewy::Index.descendants - [Chewy::Stash::Journal, Chewy::Stash::Specification]
205
196
  end
206
197
 
198
+ # Reindex data from source index to destination index
199
+ #
200
+ # @example
201
+ # Chewy::RakeHelper.reindex(source: 'users_index', dest: 'cities_index') reindex data from 'users_index' index to 'cities_index'
202
+ #
203
+ # @param source [String], dest [String] indexes to reindex
204
+ def reindex(source:, dest:, output: $stdout)
205
+ subscribed_task_stats(output) do
206
+ output.puts "Source index is #{source}\nDestination index is #{dest}"
207
+ Chewy::Index.reindex(source: source, dest: dest)
208
+ output.puts "#{source} index successfully reindexed with #{dest} index data"
209
+ end
210
+ end
211
+
212
+ # Adds new fields to an existing data stream or index.
213
+ # Change the search settings of existing fields.
214
+ #
215
+ # @example
216
+ # Chewy::RakeHelper.update_mapping('cities', {properties: {new_field: {type: :text}}}) update 'cities' index with new_field of text type
217
+ #
218
+ # @param name [String], body_hash [Hash] index name and body hash to update
219
+ def update_mapping(name:, output: $stdout)
220
+ subscribed_task_stats(output) do
221
+ output.puts "Index name is #{name}"
222
+ normalize_index(name).update_mapping
223
+ output.puts "#{name} index successfully updated"
224
+ end
225
+ end
226
+
207
227
  def normalize_indexes(*identifiers)
208
228
  identifiers.flatten(1).map { |identifier| normalize_index(identifier) }
209
229
  end
210
230
 
211
231
  def normalize_index(identifier)
212
232
  return identifier if identifier.is_a?(Class) && identifier < Chewy::Index
213
- "#{identifier.to_s.gsub(/identifier\z/i, '').camelize}Index".constantize
233
+
234
+ "#{identifier.to_s.camelize}Index".constantize
214
235
  end
215
236
 
216
- def subscribed_task_stats(output = STDOUT)
237
+ def subscribed_task_stats(output = $stdout, &block)
217
238
  start = Time.now
218
239
  ActiveSupport::Notifications.subscribed(JOURNAL_CALLBACK.curry[output], 'apply_journal.chewy') do
219
- ActiveSupport::Notifications.subscribed(IMPORT_CALLBACK.curry[output], 'import_objects.chewy') do
220
- yield
221
- end
240
+ ActiveSupport::Notifications.subscribed(IMPORT_CALLBACK.curry[output], 'import_objects.chewy', &block)
222
241
  end
223
242
  output.puts "Total: #{human_duration(Time.now - start)}"
224
243
  end
225
244
 
226
- def reset_index(*indexes)
227
- ActiveSupport::Deprecation.warn '`Chewy::RakeHelper.reset_index` is deprecated and will be removed soon, use `Chewy::RakeHelper.reset` instead'
228
- reset(only: indexes)
229
- end
230
-
231
- def reset_all(*except)
232
- ActiveSupport::Deprecation.warn '`Chewy::RakeHelper.reset_all` is deprecated and will be removed soon, use `Chewy::RakeHelper.reset` instead'
233
- reset(except: except)
234
- end
235
-
236
- def update_index(*indexes)
237
- ActiveSupport::Deprecation.warn '`Chewy::RakeHelper.update_index` is deprecated and will be removed soon, use `Chewy::RakeHelper.update` instead'
238
- update(only: indexes)
239
- end
240
-
241
- def update_all(*except)
242
- ActiveSupport::Deprecation.warn '`Chewy::RakeHelper.update_all` is deprecated and will be removed soon, use `Chewy::RakeHelper.update` instead'
243
- update(except: except)
244
- end
245
-
246
245
  private
247
246
 
248
247
  def indexes_from(only: nil, except: nil)
@@ -261,33 +260,9 @@ module Chewy
261
260
  indexes.sort_by(&:derivable_name)
262
261
  end
263
262
 
264
- def types_from(only: nil, except: nil)
265
- types = if only.present?
266
- normalize_types(Array.wrap(only))
267
- else
268
- all_indexes.flat_map(&:types)
269
- end
270
-
271
- types = if except.present?
272
- types - normalize_types(Array.wrap(except))
273
- else
274
- types
275
- end
276
-
277
- types.sort_by(&:derivable_name)
278
- end
279
-
280
- def normalize_types(*identifiers)
281
- identifiers.flatten(1).flat_map { |identifier| normalize_type(identifier) }
282
- end
283
-
284
- def normalize_type(identifier)
285
- Chewy.derive_types(identifier)
286
- end
287
-
288
263
  def human_duration(seconds)
289
264
  [[60, :s], [60, :m], [24, :h]].map do |amount, unit|
290
- if seconds > 0
265
+ if seconds.positive?
291
266
  seconds, n = seconds.divmod(amount)
292
267
  "#{n.to_i}#{unit}"
293
268
  end