chewy 0.10.1 → 7.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (243) hide show
  1. checksums.yaml +5 -5
  2. data/.github/CODEOWNERS +1 -0
  3. data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
  4. data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
  5. data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
  6. data/.github/workflows/ruby.yml +74 -0
  7. data/.rubocop.yml +28 -23
  8. data/.rubocop_todo.yml +110 -22
  9. data/CHANGELOG.md +480 -298
  10. data/CODE_OF_CONDUCT.md +14 -0
  11. data/CONTRIBUTING.md +63 -0
  12. data/Gemfile +3 -5
  13. data/Guardfile +3 -1
  14. data/LICENSE.txt +1 -1
  15. data/README.md +571 -333
  16. data/chewy.gemspec +12 -15
  17. data/gemfiles/rails.5.2.activerecord.gemfile +11 -0
  18. data/gemfiles/rails.6.0.activerecord.gemfile +11 -0
  19. data/gemfiles/rails.6.1.activerecord.gemfile +13 -0
  20. data/gemfiles/rails.7.0.activerecord.gemfile +13 -0
  21. data/lib/chewy/config.rb +48 -77
  22. data/lib/chewy/errors.rb +4 -10
  23. data/lib/chewy/fields/base.rb +88 -16
  24. data/lib/chewy/fields/root.rb +15 -21
  25. data/lib/chewy/index/actions.rb +67 -38
  26. data/lib/chewy/{type → index}/adapter/active_record.rb +18 -4
  27. data/lib/chewy/{type → index}/adapter/base.rb +11 -12
  28. data/lib/chewy/{type → index}/adapter/object.rb +28 -32
  29. data/lib/chewy/{type → index}/adapter/orm.rb +26 -24
  30. data/lib/chewy/index/aliases.rb +14 -5
  31. data/lib/chewy/index/crutch.rb +40 -0
  32. data/lib/chewy/index/import/bulk_builder.rb +311 -0
  33. data/lib/chewy/{type → index}/import/bulk_request.rb +10 -9
  34. data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
  35. data/lib/chewy/{type → index}/import/routine.rb +19 -18
  36. data/lib/chewy/{type → index}/import.rb +82 -36
  37. data/lib/chewy/{type → index}/mapping.rb +63 -62
  38. data/lib/chewy/index/observe/active_record_methods.rb +87 -0
  39. data/lib/chewy/index/observe/callback.rb +34 -0
  40. data/lib/chewy/index/observe.rb +17 -0
  41. data/lib/chewy/index/settings.rb +2 -0
  42. data/lib/chewy/index/specification.rb +13 -10
  43. data/lib/chewy/{type → index}/syncer.rb +62 -63
  44. data/lib/chewy/{type → index}/witchcraft.rb +15 -9
  45. data/lib/chewy/{type → index}/wrapper.rb +16 -6
  46. data/lib/chewy/index.rb +68 -93
  47. data/lib/chewy/journal.rb +25 -14
  48. data/lib/chewy/minitest/helpers.rb +91 -18
  49. data/lib/chewy/minitest/search_index_receiver.rb +29 -33
  50. data/lib/chewy/multi_search.rb +62 -0
  51. data/lib/chewy/railtie.rb +8 -24
  52. data/lib/chewy/rake_helper.rb +141 -112
  53. data/lib/chewy/rspec/build_query.rb +12 -0
  54. data/lib/chewy/rspec/helpers.rb +55 -0
  55. data/lib/chewy/rspec/update_index.rb +58 -49
  56. data/lib/chewy/rspec.rb +2 -0
  57. data/lib/chewy/runtime.rb +1 -1
  58. data/lib/chewy/search/loader.rb +19 -41
  59. data/lib/chewy/search/parameters/allow_partial_search_results.rb +27 -0
  60. data/lib/chewy/search/parameters/collapse.rb +16 -0
  61. data/lib/chewy/search/parameters/concerns/query_storage.rb +6 -5
  62. data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
  63. data/lib/chewy/search/parameters/indices.rb +78 -0
  64. data/lib/chewy/search/parameters/none.rb +1 -3
  65. data/lib/chewy/search/parameters/order.rb +6 -19
  66. data/lib/chewy/search/parameters/source.rb +5 -1
  67. data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
  68. data/lib/chewy/search/parameters.rb +28 -8
  69. data/lib/chewy/search/query_proxy.rb +9 -2
  70. data/lib/chewy/search/request.rb +207 -157
  71. data/lib/chewy/search/response.rb +5 -5
  72. data/lib/chewy/search/scoping.rb +7 -8
  73. data/lib/chewy/search/scrolling.rb +14 -13
  74. data/lib/chewy/search.rb +7 -26
  75. data/lib/chewy/stash.rb +27 -29
  76. data/lib/chewy/strategy/active_job.rb +2 -2
  77. data/lib/chewy/strategy/atomic.rb +1 -1
  78. data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
  79. data/lib/chewy/strategy/base.rb +10 -0
  80. data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +148 -0
  81. data/lib/chewy/strategy/delayed_sidekiq/worker.rb +52 -0
  82. data/lib/chewy/strategy/delayed_sidekiq.rb +17 -0
  83. data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
  84. data/lib/chewy/strategy/sidekiq.rb +3 -2
  85. data/lib/chewy/strategy.rb +6 -19
  86. data/lib/chewy/version.rb +1 -1
  87. data/lib/chewy.rb +37 -80
  88. data/lib/generators/chewy/install_generator.rb +1 -1
  89. data/lib/tasks/chewy.rake +26 -32
  90. data/migration_guide.md +56 -0
  91. data/spec/chewy/config_spec.rb +27 -57
  92. data/spec/chewy/fields/base_spec.rb +457 -174
  93. data/spec/chewy/fields/root_spec.rb +24 -32
  94. data/spec/chewy/fields/time_fields_spec.rb +5 -5
  95. data/spec/chewy/index/actions_spec.rb +425 -60
  96. data/spec/chewy/{type → index}/adapter/active_record_spec.rb +110 -44
  97. data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
  98. data/spec/chewy/index/aliases_spec.rb +3 -3
  99. data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
  100. data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
  101. data/spec/chewy/{type → index}/import/journal_builder_spec.rb +22 -30
  102. data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
  103. data/spec/chewy/{type → index}/import_spec.rb +154 -95
  104. data/spec/chewy/index/mapping_spec.rb +135 -0
  105. data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
  106. data/spec/chewy/index/observe/callback_spec.rb +139 -0
  107. data/spec/chewy/index/observe_spec.rb +143 -0
  108. data/spec/chewy/index/settings_spec.rb +3 -1
  109. data/spec/chewy/index/specification_spec.rb +32 -33
  110. data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
  111. data/spec/chewy/{type → index}/witchcraft_spec.rb +34 -21
  112. data/spec/chewy/index/wrapper_spec.rb +100 -0
  113. data/spec/chewy/index_spec.rb +99 -114
  114. data/spec/chewy/journal_spec.rb +56 -101
  115. data/spec/chewy/minitest/helpers_spec.rb +122 -14
  116. data/spec/chewy/minitest/search_index_receiver_spec.rb +24 -26
  117. data/spec/chewy/multi_search_spec.rb +84 -0
  118. data/spec/chewy/rake_helper_spec.rb +325 -101
  119. data/spec/chewy/rspec/build_query_spec.rb +34 -0
  120. data/spec/chewy/rspec/helpers_spec.rb +61 -0
  121. data/spec/chewy/rspec/update_index_spec.rb +106 -102
  122. data/spec/chewy/runtime_spec.rb +2 -2
  123. data/spec/chewy/search/loader_spec.rb +19 -53
  124. data/spec/chewy/search/pagination/kaminari_examples.rb +3 -5
  125. data/spec/chewy/search/pagination/kaminari_spec.rb +1 -1
  126. data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
  127. data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
  128. data/spec/chewy/search/parameters/indices_spec.rb +99 -0
  129. data/spec/chewy/search/parameters/none_spec.rb +1 -1
  130. data/spec/chewy/search/parameters/order_spec.rb +18 -11
  131. data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
  132. data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
  133. data/spec/chewy/search/parameters/source_spec.rb +8 -2
  134. data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
  135. data/spec/chewy/search/parameters_spec.rb +39 -8
  136. data/spec/chewy/search/query_proxy_spec.rb +68 -17
  137. data/spec/chewy/search/request_spec.rb +360 -149
  138. data/spec/chewy/search/response_spec.rb +35 -25
  139. data/spec/chewy/search/scrolling_spec.rb +28 -26
  140. data/spec/chewy/search_spec.rb +73 -53
  141. data/spec/chewy/stash_spec.rb +16 -26
  142. data/spec/chewy/strategy/active_job_spec.rb +23 -10
  143. data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
  144. data/spec/chewy/strategy/atomic_spec.rb +9 -10
  145. data/spec/chewy/strategy/delayed_sidekiq_spec.rb +190 -0
  146. data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
  147. data/spec/chewy/strategy/sidekiq_spec.rb +14 -10
  148. data/spec/chewy/strategy_spec.rb +19 -15
  149. data/spec/chewy_spec.rb +17 -110
  150. data/spec/spec_helper.rb +7 -22
  151. data/spec/support/active_record.rb +43 -5
  152. metadata +123 -198
  153. data/.travis.yml +0 -53
  154. data/Appraisals +0 -79
  155. data/LEGACY_DSL.md +0 -497
  156. data/gemfiles/rails.4.0.activerecord.gemfile +0 -14
  157. data/gemfiles/rails.4.1.activerecord.gemfile +0 -14
  158. data/gemfiles/rails.4.2.activerecord.gemfile +0 -15
  159. data/gemfiles/rails.4.2.mongoid.5.1.gemfile +0 -15
  160. data/gemfiles/rails.5.0.activerecord.gemfile +0 -15
  161. data/gemfiles/rails.5.0.mongoid.6.0.gemfile +0 -15
  162. data/gemfiles/rails.5.1.activerecord.gemfile +0 -15
  163. data/gemfiles/rails.5.1.mongoid.6.1.gemfile +0 -15
  164. data/gemfiles/sequel.4.45.gemfile +0 -11
  165. data/lib/chewy/backports/deep_dup.rb +0 -46
  166. data/lib/chewy/backports/duplicable.rb +0 -91
  167. data/lib/chewy/query/compose.rb +0 -68
  168. data/lib/chewy/query/criteria.rb +0 -191
  169. data/lib/chewy/query/filters.rb +0 -227
  170. data/lib/chewy/query/loading.rb +0 -111
  171. data/lib/chewy/query/nodes/and.rb +0 -25
  172. data/lib/chewy/query/nodes/base.rb +0 -17
  173. data/lib/chewy/query/nodes/bool.rb +0 -34
  174. data/lib/chewy/query/nodes/equal.rb +0 -34
  175. data/lib/chewy/query/nodes/exists.rb +0 -20
  176. data/lib/chewy/query/nodes/expr.rb +0 -28
  177. data/lib/chewy/query/nodes/field.rb +0 -110
  178. data/lib/chewy/query/nodes/has_child.rb +0 -15
  179. data/lib/chewy/query/nodes/has_parent.rb +0 -15
  180. data/lib/chewy/query/nodes/has_relation.rb +0 -59
  181. data/lib/chewy/query/nodes/match_all.rb +0 -11
  182. data/lib/chewy/query/nodes/missing.rb +0 -20
  183. data/lib/chewy/query/nodes/not.rb +0 -25
  184. data/lib/chewy/query/nodes/or.rb +0 -25
  185. data/lib/chewy/query/nodes/prefix.rb +0 -19
  186. data/lib/chewy/query/nodes/query.rb +0 -20
  187. data/lib/chewy/query/nodes/range.rb +0 -63
  188. data/lib/chewy/query/nodes/raw.rb +0 -15
  189. data/lib/chewy/query/nodes/regexp.rb +0 -35
  190. data/lib/chewy/query/nodes/script.rb +0 -20
  191. data/lib/chewy/query/pagination.rb +0 -25
  192. data/lib/chewy/query.rb +0 -1098
  193. data/lib/chewy/search/pagination/will_paginate.rb +0 -43
  194. data/lib/chewy/search/parameters/types.rb +0 -20
  195. data/lib/chewy/strategy/resque.rb +0 -27
  196. data/lib/chewy/strategy/shoryuken.rb +0 -40
  197. data/lib/chewy/type/actions.rb +0 -43
  198. data/lib/chewy/type/adapter/mongoid.rb +0 -69
  199. data/lib/chewy/type/adapter/sequel.rb +0 -95
  200. data/lib/chewy/type/crutch.rb +0 -32
  201. data/lib/chewy/type/import/bulk_builder.rb +0 -122
  202. data/lib/chewy/type/observe.rb +0 -78
  203. data/lib/chewy/type.rb +0 -117
  204. data/lib/sequel/plugins/chewy_observe.rb +0 -78
  205. data/spec/chewy/query/criteria_spec.rb +0 -700
  206. data/spec/chewy/query/filters_spec.rb +0 -201
  207. data/spec/chewy/query/loading_spec.rb +0 -124
  208. data/spec/chewy/query/nodes/and_spec.rb +0 -12
  209. data/spec/chewy/query/nodes/bool_spec.rb +0 -14
  210. data/spec/chewy/query/nodes/equal_spec.rb +0 -32
  211. data/spec/chewy/query/nodes/exists_spec.rb +0 -18
  212. data/spec/chewy/query/nodes/has_child_spec.rb +0 -59
  213. data/spec/chewy/query/nodes/has_parent_spec.rb +0 -59
  214. data/spec/chewy/query/nodes/match_all_spec.rb +0 -11
  215. data/spec/chewy/query/nodes/missing_spec.rb +0 -16
  216. data/spec/chewy/query/nodes/not_spec.rb +0 -13
  217. data/spec/chewy/query/nodes/or_spec.rb +0 -12
  218. data/spec/chewy/query/nodes/prefix_spec.rb +0 -16
  219. data/spec/chewy/query/nodes/query_spec.rb +0 -12
  220. data/spec/chewy/query/nodes/range_spec.rb +0 -32
  221. data/spec/chewy/query/nodes/raw_spec.rb +0 -11
  222. data/spec/chewy/query/nodes/regexp_spec.rb +0 -43
  223. data/spec/chewy/query/nodes/script_spec.rb +0 -15
  224. data/spec/chewy/query/pagination/kaminari_spec.rb +0 -5
  225. data/spec/chewy/query/pagination/will_paginate_spec.rb +0 -5
  226. data/spec/chewy/query/pagination_spec.rb +0 -39
  227. data/spec/chewy/query_spec.rb +0 -636
  228. data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
  229. data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
  230. data/spec/chewy/search/parameters/indices_boost_spec.rb +0 -83
  231. data/spec/chewy/search/parameters/types_spec.rb +0 -5
  232. data/spec/chewy/strategy/resque_spec.rb +0 -46
  233. data/spec/chewy/strategy/shoryuken_spec.rb +0 -64
  234. data/spec/chewy/type/actions_spec.rb +0 -50
  235. data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
  236. data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
  237. data/spec/chewy/type/import/bulk_builder_spec.rb +0 -279
  238. data/spec/chewy/type/mapping_spec.rb +0 -142
  239. data/spec/chewy/type/observe_spec.rb +0 -137
  240. data/spec/chewy/type/wrapper_spec.rb +0 -98
  241. data/spec/chewy/type_spec.rb +0 -55
  242. data/spec/support/mongoid.rb +0 -93
  243. data/spec/support/sequel.rb +0 -80
@@ -1,43 +0,0 @@
1
- module Chewy
2
- module Search
3
- module Pagination
4
- # This module provides `WillPaginate` support for {Chewy::Search::Request}
5
- # It is included automatically if `WillPaginate` is available.
6
- #
7
- # @example
8
- # PlacesIndex.all.paginate(page: 3, per_page: 10).order(:name)
9
- # # => <PlacesIndex::Query {..., :body=>{:size=>10, :from=>20, :sort=>["name"]}}>
10
- module WillPaginate
11
- extend ActiveSupport::Concern
12
-
13
- included do
14
- include ::WillPaginate::CollectionMethods
15
- attr_reader :current_page, :per_page
16
- end
17
-
18
- def paginate(options = {})
19
- @current_page = ::WillPaginate::PageNumber(options[:page] || @current_page || 1)
20
- @page_multiplier = @current_page - 1
21
- @per_page = (options[:per_page] || @per_page || ::WillPaginate.per_page).to_i
22
-
23
- # call Chewy::Query methods to limit results
24
- limit(@per_page).offset(@page_multiplier * @per_page)
25
- end
26
-
27
- def page(page)
28
- paginate(page: page)
29
- end
30
-
31
- private
32
-
33
- def paginated_collection(collection)
34
- page = current_page || 1
35
- per = per_page || ::WillPaginate.per_page
36
- ::WillPaginate::Collection.create(page, per, total_entries) do |pager|
37
- pager.replace collection
38
- end
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,20 +0,0 @@
1
- require 'chewy/search/parameters/storage'
2
-
3
- module Chewy
4
- module Search
5
- class Parameters
6
- # A standard string array storage with one exception: rendering is empty.
7
- #
8
- # @see Chewy::Search::Parameters::StringArrayStorage
9
- class Types < Storage
10
- include StringArrayStorage
11
-
12
- # Doesn't render anything, has specialized rendering logic in
13
- # {Chewy::Search::Request}
14
- #
15
- # @return [nil]
16
- def render; end
17
- end
18
- end
19
- end
20
- end
@@ -1,27 +0,0 @@
1
- module Chewy
2
- class Strategy
3
- # The strategy works the same way as atomic, but performs
4
- # async index update driven by resque
5
- #
6
- # Chewy.strategy(:resque) do
7
- # User.all.map(&:save) # Does nothing here
8
- # Post.all.map(&:save) # And here
9
- # # It imports all the changed users and posts right here
10
- # end
11
- #
12
- class Resque < Atomic
13
- class Worker
14
- @queue = :chewy
15
-
16
- def self.perform(type, ids, options = {})
17
- options[:refresh] = !Chewy.disable_refresh_async if Chewy.disable_refresh_async
18
- type.constantize.import!(ids, options)
19
- end
20
- end
21
-
22
- def leave
23
- @stash.all? { |type, ids| ::Resque.enqueue(Chewy::Strategy::Resque::Worker, type.name, ids) }
24
- end
25
- end
26
- end
27
- end
@@ -1,40 +0,0 @@
1
- module Chewy
2
- class Strategy
3
- # The strategy works the same way as atomic, but performs
4
- # async index update driven by shoryuken
5
- #
6
- # Chewy.strategy(:shoryuken) do
7
- # User.all.map(&:save) # Does nothing here
8
- # Post.all.map(&:save) # And here
9
- # # It imports all the changed users and posts right here
10
- # end
11
- #
12
- class Shoryuken < Atomic
13
- class Worker
14
- include ::Shoryuken::Worker
15
-
16
- shoryuken_options auto_delete: true,
17
- body_parser: :json
18
-
19
- def perform(_sqs_msg, body)
20
- options = body['options'] || {}
21
- options[:refresh] = !Chewy.disable_refresh_async if Chewy.disable_refresh_async
22
- body['type'].constantize.import!(body['ids'], options.deep_symbolize_keys!)
23
- end
24
- end
25
-
26
- def leave
27
- @stash.each do |type, ids|
28
- next if ids.empty?
29
- Shoryuken::Worker.perform_async({type: type.name, ids: ids}, queue: shoryuken_queue)
30
- end
31
- end
32
-
33
- private
34
-
35
- def shoryuken_queue
36
- Chewy.settings.fetch(:shoryuken, {})[:queue] || 'chewy'
37
- end
38
- end
39
- end
40
- end
@@ -1,43 +0,0 @@
1
- module Chewy
2
- class Type
3
- module Actions
4
- extend ActiveSupport::Concern
5
-
6
- module ClassMethods
7
- # Deletes all documents of a type and reimports them
8
- #
9
- # @example
10
- # UsersIndex::User.reset
11
- #
12
- # @see Chewy::Type::Import::ClassMethods#import
13
- # @see Chewy::Type::Import::ClassMethods#import
14
- # @return [true, false] the result of import
15
- def reset
16
- delete_all
17
- import
18
- end
19
-
20
- # Performs missing and outdated objects synchronization for the current type.
21
- #
22
- # @example
23
- # UsersIndex::User.sync
24
- #
25
- # @see Chewy::Type::Syncer
26
- # @param parallel [true, Integer, Hash] options for parallel execution or the number of processes
27
- # @return [Hash{Symbol, Object}, nil] a number of missing and outdated documents reindexed and their ids, nil in case of errors
28
- def sync(parallel: nil)
29
- syncer = Syncer.new(self, parallel: parallel)
30
- count = syncer.perform
31
- {count: count, missing: syncer.missing_ids, outdated: syncer.outdated_ids} if count
32
- end
33
-
34
- # A {Chewy::Journal} instance for the particular type
35
- #
36
- # @return [Chewy::Journal] journal instance
37
- def journal
38
- @journal ||= Chewy::Journal.new(self)
39
- end
40
- end
41
- end
42
- end
43
- end
@@ -1,69 +0,0 @@
1
- require 'chewy/type/adapter/orm'
2
-
3
- module Chewy
4
- class Type
5
- module Adapter
6
- class Mongoid < Orm
7
- def self.accepts?(target)
8
- defined?(::Mongoid::Document) && (
9
- target.is_a?(Class) && target.ancestors.include?(::Mongoid::Document) ||
10
- target.is_a?(::Mongoid::Criteria))
11
- end
12
-
13
- def identify(collection)
14
- super(collection).map { |id| id.is_a?(BSON::ObjectId) ? id.to_s : id }
15
- end
16
-
17
- private
18
-
19
- def cleanup_default_scope!
20
- if Chewy.logger && @default_scope.options.values_at(:sort, :limit, :skip).compact.present?
21
- Chewy.logger.warn('Default type scope order, limit and offset are ignored and will be nullified')
22
- end
23
-
24
- @default_scope.options.delete(:limit)
25
- @default_scope.options.delete(:skip)
26
- @default_scope = @default_scope.reorder(nil)
27
- end
28
-
29
- def import_scope(scope, options)
30
- pluck_in_batches(scope, options.slice(:batch_size)).map do |ids|
31
- yield grouped_objects(default_scope_where_ids_in(ids))
32
- end.all?
33
- end
34
-
35
- def primary_key
36
- :_id
37
- end
38
-
39
- def pluck(scope, fields: [])
40
- scope.pluck(primary_key, *fields)
41
- end
42
-
43
- def pluck_in_batches(scope, fields: [], batch_size: nil, **options)
44
- return enum_for(:pluck_in_batches, scope, fields: fields, batch_size: batch_size, **options) unless block_given?
45
-
46
- scope.batch_size(batch_size).no_timeout.pluck(primary_key, *fields).each_slice(batch_size) do |batch|
47
- yield batch
48
- end
49
- end
50
-
51
- def scope_where_ids_in(scope, ids)
52
- scope.where(primary_key.in => ids)
53
- end
54
-
55
- def all_scope
56
- target.all
57
- end
58
-
59
- def relation_class
60
- ::Mongoid::Criteria
61
- end
62
-
63
- def object_class
64
- ::Mongoid::Document
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,95 +0,0 @@
1
- require 'chewy/type/adapter/base'
2
-
3
- module Chewy
4
- class Type
5
- module Adapter
6
- class Sequel < Orm
7
- attr_reader :default_scope
8
- alias_method :default_dataset, :default_scope
9
-
10
- def self.accepts?(target)
11
- defined?(::Sequel::Model) && (
12
- target.is_a?(Class) && target < ::Sequel::Model ||
13
- target.is_a?(::Sequel::Dataset))
14
- end
15
-
16
- private
17
-
18
- def cleanup_default_scope!
19
- if Chewy.logger && @default_scope != @default_scope.unordered.unlimited
20
- Chewy.logger.warn('Default type scope order, limit and offset are ignored and will be nullified')
21
- end
22
-
23
- @default_scope = @default_scope.unordered.unlimited
24
- end
25
-
26
- def import_scope(scope, options)
27
- pluck_in_batches(scope, options.slice(:batch_size)).inject(true) do |result, ids|
28
- result & yield(grouped_objects(default_scope_where_ids_in(ids).all))
29
- end
30
- end
31
-
32
- def primary_key
33
- target.primary_key
34
- end
35
-
36
- def full_column_name(column)
37
- "#{target.table_name}__#{column}".to_sym
38
- end
39
-
40
- def all_scope
41
- target.dataset
42
- end
43
-
44
- def target_columns
45
- @target_columns ||= target.columns.to_set
46
- end
47
-
48
- def pluck(scope, fields: [])
49
- fields = fields.map(&:to_sym).unshift(primary_key).map do |column|
50
- target_columns.include?(column) ? full_column_name(column) : column
51
- end
52
- scope.distinct.select_map(fields.one? ? fields.first : fields)
53
- end
54
-
55
- def pluck_in_batches(scope, fields: [], batch_size: nil, **options)
56
- return enum_for(:pluck_in_batches, scope, fields: fields, batch_size: batch_size, **options) unless block_given?
57
-
58
- scope = scope.unordered.order(::Sequel.asc(full_column_name(primary_key))).limit(batch_size)
59
-
60
- ids = pluck(scope, fields: fields)
61
- count = 0
62
-
63
- while ids.present?
64
- yield ids
65
- break if ids.size < batch_size
66
- last_id = ids.last.is_a?(Array) ? ids.last.first : ids.last
67
- ids = pluck(scope.where { |o| o.__send__(full_column_name(primary_key)) > last_id }, fields: fields)
68
- end
69
-
70
- count
71
- end
72
-
73
- def scope_where_ids_in(scope, ids)
74
- scope.where(full_column_name(primary_key) => Array.wrap(ids))
75
- end
76
-
77
- def model_of_relation(relation)
78
- relation.model
79
- end
80
-
81
- def relation_class
82
- ::Sequel::Dataset
83
- end
84
-
85
- def object_class
86
- ::Sequel::Model
87
- end
88
-
89
- def load_scope_objects(*args)
90
- super.all
91
- end
92
- end
93
- end
94
- end
95
- end
@@ -1,32 +0,0 @@
1
- module Chewy
2
- class Type
3
- module Crutch
4
- extend ActiveSupport::Concern
5
-
6
- included do
7
- class_attribute :_crutches
8
- self._crutches = {}
9
- end
10
-
11
- class Crutches
12
- def initialize(type, collection)
13
- @type = type
14
- @collection = collection
15
- @type._crutches.keys.each do |name|
16
- singleton_class.class_eval <<-METHOD, __FILE__, __LINE__ + 1
17
- def #{name}
18
- @#{name} ||= @type._crutches[:#{name}].call @collection
19
- end
20
- METHOD
21
- end
22
- end
23
- end
24
-
25
- module ClassMethods
26
- def crutch(name, &block)
27
- self._crutches = _crutches.merge(name.to_sym => block)
28
- end
29
- end
30
- end
31
- end
32
- end
@@ -1,122 +0,0 @@
1
- module Chewy
2
- class Type
3
- module Import
4
- # This class purpose is to build ES client-acceptable bulk
5
- # request body from the passed objects for index and deletion.
6
- # It handles parent-child relationships as well by fetching
7
- # existing documents from ES, taking their `_parent` field and
8
- # using it in the bulk body.
9
- # If fields are passed - it creates partial update entries except for
10
- # the cases when the type has parent and parent_id has been changed.
11
- class BulkBuilder
12
- # @param type [Chewy::Type] desired type
13
- # @param index [Array<Object>] objects to index
14
- # @param delete [Array<Object>] objects or ids to delete
15
- # @param fields [Array<Symbol, String>] and array of fields for documents update
16
- def initialize(type, index: [], delete: [], fields: [])
17
- @type = type
18
- @index = index
19
- @delete = delete
20
- @fields = fields.map!(&:to_sym)
21
- end
22
-
23
- # Returns ES API-ready bulk requiest body.
24
- # @see https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-api/lib/elasticsearch/api/actions/bulk.rb
25
- # @return [Array<Hash>] bulk body
26
- def bulk_body
27
- @bulk_body ||= @index.flat_map(&method(:index_entry)).concat(
28
- @delete.flat_map(&method(:delete_entry))
29
- )
30
- end
31
-
32
- # The only purpose of this method is to cache document ids for
33
- # all the passed object for index to avoid ids recalculation.
34
- #
35
- # @return [Hash[String => Object]] an ids-objects index hash
36
- def index_objects_by_id
37
- @index_objects_by_id ||= index_object_ids.invert.stringify_keys!
38
- end
39
-
40
- private
41
-
42
- def crutches
43
- @crutches ||= Chewy::Type::Crutch::Crutches.new @type, @index
44
- end
45
-
46
- def parents
47
- return unless type_root.parent_id
48
-
49
- @parents ||= begin
50
- ids = @index.map do |object|
51
- object.respond_to?(:id) ? object.id : object
52
- end
53
- ids.concat(@delete.map do |object|
54
- object.respond_to?(:id) ? object.id : object
55
- end)
56
- @type.filter(ids: {values: ids}).order('_doc').pluck(:_id, :_parent).to_h
57
- end
58
- end
59
-
60
- def index_entry(object)
61
- entry = {}
62
- entry[:_id] = index_object_ids[object] if index_object_ids[object]
63
-
64
- if parents
65
- entry[:parent] = type_root.compose_parent(object)
66
- parent = entry[:_id].present? && parents[entry[:_id].to_s]
67
- end
68
-
69
- if parent && entry[:parent].to_s != parent
70
- entry[:data] = @type.compose(object, crutches)
71
- [{delete: entry.except(:data).merge(parent: parent)}, {index: entry}]
72
- elsif @fields.present?
73
- return [] unless entry[:_id]
74
- entry[:data] = {doc: @type.compose(object, crutches, fields: @fields)}
75
- [{update: entry}]
76
- else
77
- entry[:data] = @type.compose(object, crutches)
78
- [{index: entry}]
79
- end
80
- end
81
-
82
- def delete_entry(object)
83
- entry = {}
84
- entry[:_id] = entry_id(object)
85
- entry[:_id] ||= object.as_json
86
-
87
- return [] if entry[:_id].blank?
88
-
89
- if parents
90
- parent = entry[:_id].present? && parents[entry[:_id].to_s]
91
- return [] unless parent
92
- entry[:parent] = parent
93
- end
94
-
95
- [{delete: entry}]
96
- end
97
-
98
- def entry_id(object)
99
- if type_root.id
100
- type_root.compose_id(object)
101
- else
102
- id = object.id if object.respond_to?(:id)
103
- id ||= object[:id] || object['id'] if object.is_a?(Hash)
104
- id = id.to_s if defined?(BSON) && id.is_a?(BSON::ObjectId)
105
- id
106
- end
107
- end
108
-
109
- def index_object_ids
110
- @index_object_ids ||= @index.each_with_object({}) do |object, result|
111
- id = entry_id(object)
112
- result[object] = id if id.present?
113
- end
114
- end
115
-
116
- def type_root
117
- @type_root = @type.send(:build_root)
118
- end
119
- end
120
- end
121
- end
122
- end
@@ -1,78 +0,0 @@
1
- module Chewy
2
- class Type
3
- module Observe
4
- extend ActiveSupport::Concern
5
-
6
- module Helpers
7
- def update_proc(type_name, *args, &block)
8
- options = args.extract_options!
9
- method = args.first
10
-
11
- proc do
12
- backreference = if method && method.to_s == 'self'
13
- self
14
- elsif method
15
- send(method)
16
- else
17
- instance_eval(&block)
18
- end
19
-
20
- reference = if type_name.is_a?(Proc)
21
- if type_name.arity.zero?
22
- instance_exec(&type_name)
23
- else
24
- type_name.call(self)
25
- end
26
- else
27
- type_name
28
- end
29
-
30
- Chewy.derive_type(reference).update_index(backreference, options)
31
- end
32
- end
33
-
34
- def extract_callback_options!(args)
35
- options = args.extract_options!
36
- result = options.each_key.with_object({}) do |key, hash|
37
- hash[key] = options.delete(key) if %i[if unless].include?(key)
38
- end
39
- args.push(options) unless options.empty?
40
- result
41
- end
42
- end
43
-
44
- extend Helpers
45
-
46
- module MongoidMethods
47
- def update_index(type_name, *args, &block)
48
- callback_options = Observe.extract_callback_options!(args)
49
- update_proc = Observe.update_proc(type_name, *args, &block)
50
-
51
- after_save(callback_options, &update_proc)
52
- after_destroy(callback_options, &update_proc)
53
- end
54
- end
55
-
56
- module ActiveRecordMethods
57
- def update_index(type_name, *args, &block)
58
- callback_options = Observe.extract_callback_options!(args)
59
- update_proc = Observe.update_proc(type_name, *args, &block)
60
-
61
- if Chewy.use_after_commit_callbacks
62
- after_commit(callback_options, &update_proc)
63
- else
64
- after_save(callback_options, &update_proc)
65
- after_destroy(callback_options, &update_proc)
66
- end
67
- end
68
- end
69
-
70
- module ClassMethods
71
- def update_index(objects, options = {})
72
- Chewy.strategy.current.update(self, objects, options)
73
- true
74
- end
75
- end
76
- end
77
- end
78
- end
data/lib/chewy/type.rb DELETED
@@ -1,117 +0,0 @@
1
- require 'chewy/search'
2
- require 'chewy/type/adapter/object'
3
- require 'chewy/type/adapter/active_record'
4
- require 'chewy/type/adapter/mongoid'
5
- require 'chewy/type/adapter/sequel'
6
- require 'chewy/type/mapping'
7
- require 'chewy/type/wrapper'
8
- require 'chewy/type/observe'
9
- require 'chewy/type/actions'
10
- require 'chewy/type/syncer'
11
- require 'chewy/type/crutch'
12
- require 'chewy/type/import'
13
- require 'chewy/type/witchcraft'
14
-
15
- module Chewy
16
- class Type
17
- IMPORT_OPTIONS_KEYS = %i[batch_size bulk_size refresh consistency replication raw_import journal].freeze
18
-
19
- include Search
20
- include Mapping
21
- include Wrapper
22
- include Observe
23
- include Actions
24
- include Crutch
25
- include Witchcraft
26
- include Import
27
-
28
- singleton_class.delegate :index_name, :derivable_index_name, :client, to: :index
29
-
30
- class_attribute :_default_import_options
31
- self._default_import_options = {}
32
-
33
- class << self
34
- # Chewy index current type belongs to. Defined inside `Chewy.create_type`
35
- #
36
- def index
37
- raise NotImplementedError, 'Looks like this type ws defined outside the index scope and `.index` method is undefined for it'
38
- end
39
-
40
- # Current type adapter. Defined inside `Chewy.create_type`, derived from
41
- # `Chewy::Index.define_type` arguments.
42
- #
43
- def adapter
44
- raise NotImplementedError
45
- end
46
-
47
- # Returns type name string
48
- #
49
- def type_name
50
- adapter.type_name
51
- end
52
-
53
- # Appends type name to {Chewy::Index.derivable_name}
54
- #
55
- # @example
56
- # class Namespace::UsersIndex < Chewy::Index
57
- # define_type User
58
- # end
59
- # UsersIndex::User.derivable_name # => 'namespace/users#user'
60
- #
61
- # @see Chewy::Index.derivable_name
62
- # @return [String, nil] derivable name or nil when it is impossible to calculate
63
- def derivable_name
64
- @derivable_name ||= [index.derivable_name, type_name].join('#') if index && index.derivable_name
65
- end
66
-
67
- # This method is an API shared with {Chewy::Index}, added for convenience.
68
- #
69
- # @return [Chewy::Type] array containing itself
70
- def types
71
- [self]
72
- end
73
-
74
- # Returns list of public class methods defined in current type
75
- #
76
- def scopes
77
- public_methods - Chewy::Type.public_methods
78
- end
79
-
80
- def default_import_options(params)
81
- params.assert_valid_keys(IMPORT_OPTIONS_KEYS)
82
- self._default_import_options = _default_import_options.merge(params)
83
- end
84
-
85
- def method_missing(method, *args, &block)
86
- if index.scopes.include?(method)
87
- define_singleton_method method do |*method_args, &method_block|
88
- all.scoping { index.public_send(method, *method_args, &method_block) }
89
- end
90
- send(method, *args, &block)
91
- else
92
- super
93
- end
94
- end
95
-
96
- def respond_to_missing?(method, _)
97
- index.scopes.include?(method) || super
98
- end
99
-
100
- def const_missing(name)
101
- to_resolve = "#{self}::#{name}"
102
- to_resolve[index.to_s] = ''
103
-
104
- @__resolved_constants ||= {}
105
-
106
- if to_resolve.empty? || @__resolved_constants[to_resolve]
107
- super
108
- else
109
- @__resolved_constants[to_resolve] = true
110
- to_resolve.constantize
111
- end
112
- rescue NotImplementedError
113
- super
114
- end
115
- end
116
- end
117
- end