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
data/chewy.gemspec CHANGED
@@ -1,14 +1,12 @@
1
- # coding: utf-8
2
-
3
- lib = File.expand_path('../lib', __FILE__)
1
+ lib = File.expand_path('lib', __dir__)
4
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
3
  require 'chewy/version'
6
4
 
7
- Gem::Specification.new do |spec| # rubocop:disable BlockLength
5
+ Gem::Specification.new do |spec| # rubocop:disable Metrics/BlockLength
8
6
  spec.name = 'chewy'
9
7
  spec.version = Chewy::VERSION
10
- spec.authors = ['pyromaniac']
11
- spec.email = ['kinwizard@gmail.com']
8
+ spec.authors = ['Toptal, LLC', 'pyromaniac']
9
+ spec.email = ['open-source@toptal.com', 'kinwizard@gmail.com']
12
10
  spec.summary = 'Elasticsearch ODM client wrapper'
13
11
  spec.description = 'Chewy provides functionality for Elasticsearch index handling, documents import mappings and chainable query DSL'
14
12
  spec.homepage = 'https://github.com/toptal/chewy'
@@ -19,22 +17,21 @@ Gem::Specification.new do |spec| # rubocop:disable BlockLength
19
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
18
  spec.require_paths = ['lib']
21
19
 
20
+ spec.add_development_dependency 'database_cleaner'
21
+ spec.add_development_dependency 'elasticsearch-extensions'
22
+ spec.add_development_dependency 'mock_redis'
22
23
  spec.add_development_dependency 'rake'
23
- spec.add_development_dependency 'appraisal'
24
- spec.add_development_dependency 'rspec'
25
- spec.add_development_dependency 'rspec-its'
24
+ spec.add_development_dependency 'rspec', '>= 3.7.0'
26
25
  spec.add_development_dependency 'rspec-collection_matchers'
26
+ spec.add_development_dependency 'rspec-its'
27
+ spec.add_development_dependency 'rubocop', '1.11'
27
28
  spec.add_development_dependency 'sqlite3'
28
- spec.add_development_dependency 'database_cleaner'
29
- spec.add_development_dependency 'elasticsearch-extensions'
30
- spec.add_development_dependency 'resque_spec'
31
29
  spec.add_development_dependency 'timecop'
32
- spec.add_development_dependency 'rubocop', '0.48.1'
33
30
 
34
31
  spec.add_development_dependency 'method_source'
35
32
  spec.add_development_dependency 'unparser'
36
33
 
37
- spec.add_dependency 'activesupport', '>= 4.0'
38
- spec.add_dependency 'elasticsearch', '>= 2.0.0'
34
+ spec.add_dependency 'activesupport', '>= 5.2'
35
+ spec.add_dependency 'elasticsearch', '>= 7.12.0', '< 7.14.0'
39
36
  spec.add_dependency 'elasticsearch-dsl'
40
37
  end
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activejob', '~> 5.2.0'
4
+ gem 'activerecord', '~> 5.2.0'
5
+ gem 'activesupport', '~> 5.2.0'
6
+ gem 'kaminari-core', '~> 1.1.0', require: false
7
+ gem 'parallel', require: false
8
+ gem 'rspec_junit_formatter', '~> 0.4.1'
9
+ gem 'sidekiq', require: false
10
+
11
+ gemspec path: '../'
@@ -0,0 +1,11 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activejob', '~> 6.0.0'
4
+ gem 'activerecord', '~> 6.0.0'
5
+ gem 'activesupport', '~> 6.0.0'
6
+ gem 'kaminari-core', '~> 1.1.0', require: false
7
+ gem 'parallel', require: false
8
+ gem 'rspec_junit_formatter', '~> 0.4.1'
9
+ gem 'sidekiq', require: false
10
+
11
+ gemspec path: '../'
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activejob', '~> 6.1.0'
4
+ gem 'activerecord', '~> 6.1.0'
5
+ gem 'activesupport', '~> 6.1.0'
6
+ gem 'kaminari-core', '~> 1.1.0', require: false
7
+ gem 'parallel', require: false
8
+ gem 'rspec_junit_formatter', '~> 0.4.1'
9
+ gem 'sidekiq', require: false
10
+
11
+ gem 'rexml' if RUBY_VERSION >= '3.0.0'
12
+
13
+ gemspec path: '../'
@@ -0,0 +1,13 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'activejob', '~> 7.0.0'
4
+ gem 'activerecord', '~> 7.0.0'
5
+ gem 'activesupport', '~> 7.0.0'
6
+ gem 'kaminari-core', '~> 1.1.0', require: false
7
+ gem 'parallel', require: false
8
+ gem 'rspec_junit_formatter', '~> 0.4.1'
9
+ gem 'sidekiq', require: false
10
+
11
+ gem 'rexml' if RUBY_VERSION >= '3.0.0'
12
+
13
+ gemspec path: '../'
data/lib/chewy/config.rb CHANGED
@@ -2,67 +2,47 @@ module Chewy
2
2
  class Config
3
3
  include Singleton
4
4
 
5
- attr_accessor :settings, :transport_logger, :transport_tracer, :logger,
6
-
7
- # Default query compilation mode. `:must` by default.
8
- # See Chewy::Query#query_mode for details
9
- #
10
- :query_mode,
11
-
12
- # Default filters compilation mode. `:and` by default.
13
- # See Chewy::Query#filter_mode for details
14
- #
15
- :filter_mode,
16
-
17
- # Default post_filters compilation mode. `nil` by default.
18
- # See Chewy::Query#post_filter_mode for details
19
- #
20
- :post_filter_mode,
21
-
22
- # The first strategy in stack. `:base` by default.
23
- # If you need to return to the previous chewy behavior -
24
- # just set it to `:bypass`
25
- #
26
- :root_strategy,
27
-
28
- # Default request strategy middleware, used in e.g
29
- # Rails controllers. See Chewy::Railtie::RequestStrategy
30
- # for more info.
31
- #
32
- :request_strategy,
33
-
34
- # Use after_commit callbacks for RDBMS instead of
35
- # after_save and after_destroy. True by default. Useful
36
- # in tests with transactional fixtures or transactional
37
- # DatabaseCleaner strategy.
38
- #
39
- :use_after_commit_callbacks,
40
-
41
- # Where Chewy expects to find index definitions
42
- # within a Rails app folder.
43
- :indices_path,
44
-
45
- # Set index refresh_interval setting to -1 before reset and put the original value after.
46
- # If setting not present, put back to default 1s
47
- # https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
48
- :reset_disable_refresh_interval,
49
-
50
- # Set number_of_replicas to 0 before reset and put the original value after
51
- # https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
52
- :reset_no_replicas,
53
-
54
- # Refresh or not when import async (sidekiq, resque, activejob)
55
- :disable_refresh_async,
56
-
57
- # Default options for root of Chewy type. Allows to set default options
58
- # for type mappings like `_all`.
59
- :default_root_options,
60
-
61
- # Default field type for any field in any Chewy type. Defaults to 'string'.
62
- :default_field_type,
63
-
64
- # Chewy search request DSL base class, used by every index.
65
- :search_class
5
+ attr_accessor :settings, :logger,
6
+ # The first strategy in stack. `:base` by default.
7
+ # If you need to return to the previous chewy behavior -
8
+ # just set it to `:bypass`
9
+ #
10
+ :root_strategy,
11
+ # Default request strategy middleware, used in e.g
12
+ # Rails controllers. See Chewy::Railtie::RequestStrategy
13
+ # for more info.
14
+ #
15
+ :request_strategy,
16
+ # Rails console strategy, `:urgent` by default.
17
+ #
18
+ :console_strategy,
19
+ # Use after_commit callbacks for RDBMS instead of
20
+ # after_save and after_destroy. True by default. Useful
21
+ # in tests with transactional fixtures or transactional
22
+ # DatabaseCleaner strategy.
23
+ #
24
+ :use_after_commit_callbacks,
25
+ # Where Chewy expects to find index definitions
26
+ # within a Rails app folder.
27
+ :indices_path,
28
+ # Set index refresh_interval setting to -1 before reset and put the original value after.
29
+ # If setting not present, put back to default 1s
30
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
31
+ :reset_disable_refresh_interval,
32
+ # Set number_of_replicas to 0 before reset and put the original value after
33
+ # https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-update-settings.html
34
+ :reset_no_replicas,
35
+ # Refresh or not when import async (sidekiq, lazy_sidekiq, activejob)
36
+ :disable_refresh_async,
37
+ # Default options for root of Chewy type. Allows to set default options
38
+ # for type mappings like `_all`.
39
+ :default_root_options,
40
+ # Default field type for any field in any Chewy type. Defaults to 'text'.
41
+ :default_field_type
42
+
43
+ attr_reader :transport_logger, :transport_tracer,
44
+ # Chewy search request DSL base class, used by every index.
45
+ :search_class
66
46
 
67
47
  def self.delegated
68
48
  public_instance_methods - superclass.public_instance_methods - Singleton.public_instance_methods
@@ -70,18 +50,17 @@ module Chewy
70
50
 
71
51
  def initialize
72
52
  @settings = {}
73
- @query_mode = :must
74
- @filter_mode = :and
75
53
  @root_strategy = :base
76
54
  @request_strategy = :atomic
55
+ @console_strategy = :urgent
77
56
  @use_after_commit_callbacks = true
78
57
  @reset_disable_refresh_interval = false
79
58
  @reset_no_replicas = false
80
59
  @disable_refresh_async = false
81
60
  @indices_path = 'app/chewy'
82
61
  @default_root_options = {}
83
- @default_field_type = 'string'.freeze
84
- self.search_class = Chewy::Search::Request
62
+ @default_field_type = 'text'.freeze
63
+ @search_class = build_search_class(Chewy::Search::Request)
85
64
  end
86
65
 
87
66
  def transport_logger=(logger)
@@ -94,10 +73,6 @@ module Chewy
94
73
  @transport_tracer = tracer
95
74
  end
96
75
 
97
- def search_class=(base)
98
- @search_class = build_search_class(base)
99
- end
100
-
101
76
  # Chewy core configurations. There is two ways to set it up:
102
77
  # use `Chewy.settings=` method or, for Rails application,
103
78
  # create `config/chewy.yml` file. Btw, `config/chewy.yml` supports
@@ -124,7 +99,7 @@ module Chewy
124
99
  #
125
100
  # :wait_for_status - if this option set - chewy actions such
126
101
  # as creating or deleting index, importing data will wait for
127
- # the status specified. Extremely useful for tests under havy
102
+ # the status specified. Extremely useful for tests under heavy
128
103
  # indexes manipulations.
129
104
  #
130
105
  # test:
@@ -153,12 +128,12 @@ module Chewy
153
128
 
154
129
  def yaml_settings
155
130
  @yaml_settings ||= begin
156
- if defined?(Rails)
131
+ if defined?(Rails::VERSION)
157
132
  file = Rails.root.join('config', 'chewy.yml')
158
133
 
159
134
  if File.exist?(file)
160
135
  yaml = ERB.new(File.read(file)).result
161
- hash = YAML.load(yaml) # rubocop:disable Security/YAMLLoad
136
+ hash = YAML.respond_to?(:unsafe_load) ? YAML.unsafe_load(yaml) : YAML.load(yaml) # rubocop:disable Security/YAMLLoad
162
137
  hash[Rails.env].try(:deep_symbolize_keys) if hash
163
138
  end
164
139
  end || {}
@@ -167,11 +142,7 @@ module Chewy
167
142
 
168
143
  def build_search_class(base)
169
144
  Class.new(base).tap do |search_class|
170
- if defined?(::Kaminari)
171
- search_class.include Chewy::Search::Pagination::Kaminari
172
- elsif defined?(::WillPaginate)
173
- search_class.include Chewy::Search::Pagination::WillPaginate
174
- end
145
+ search_class.send :include, Chewy::Search::Pagination::Kaminari if defined?(::Kaminari)
175
146
  end
176
147
  end
177
148
  end
data/lib/chewy/errors.rb CHANGED
@@ -5,12 +5,6 @@ module Chewy
5
5
  class UndefinedIndex < Error
6
6
  end
7
7
 
8
- class UndefinedType < Error
9
- end
10
-
11
- class UnderivableType < Error
12
- end
13
-
14
8
  class UndefinedUpdateStrategy < Error
15
9
  def initialize(_type)
16
10
  super <<-MESSAGE
@@ -37,9 +31,9 @@ module Chewy
37
31
  end
38
32
  end
39
33
 
40
- class RemovedFeature < Error
41
- end
42
-
43
- class PluginMissing < Error
34
+ class InvalidJoinFieldType < Error
35
+ def initialize(join_field_type, join_field_name, relations)
36
+ super("`#{join_field_type}` set for the join field `#{join_field_name}` is not on the :relations list (#{relations})")
37
+ end
44
38
  end
45
39
  end
@@ -1,14 +1,21 @@
1
1
  module Chewy
2
2
  module Fields
3
3
  class Base
4
- attr_reader :name, :options, :value, :children
5
- attr_accessor :parent
4
+ attr_reader :name, :join_options, :options, :children
5
+ attr_accessor :parent # used by Chewy::Index::Mapping to expand nested fields
6
6
 
7
- def initialize(name, options = {})
7
+ def initialize(name, value: nil, **options)
8
8
  @name = name.to_sym
9
- @options = options.deep_symbolize_keys
10
- @value = @options.delete(:value)
9
+ @options = {}
10
+ update_options!(**options)
11
+ @value = value
11
12
  @children = []
13
+ @allowed_relations = find_allowed_relations(options[:relations]) # for join fields
14
+ end
15
+
16
+ def update_options!(**options)
17
+ @join_options = options.delete(:join) || {}
18
+ @options = options
12
19
  end
13
20
 
14
21
  def multi_field?
@@ -26,14 +33,17 @@ module Chewy
26
33
  else
27
34
  {}
28
35
  end
29
- mapping.reverse_merge!(options)
36
+ mapping.reverse_merge!(options.except(:ignore_blank))
30
37
  mapping.reverse_merge!(type: (children.present? ? 'object' : Chewy.default_field_type))
38
+
31
39
  {name => mapping}
32
40
  end
33
41
 
34
42
  def compose(*objects)
35
43
  result = evaluate(objects)
36
44
 
45
+ return {} if result.blank? && ignore_blank?
46
+
37
47
  if children.present? && !multi_field?
38
48
  result = if result.respond_to?(:to_ary)
39
49
  result.to_ary.map { |item| compose_children(item, *objects) }
@@ -45,22 +55,70 @@ module Chewy
45
55
  {name => result}
46
56
  end
47
57
 
58
+ def value
59
+ if join_field?
60
+ join_type = join_options[:type]
61
+ join_id = join_options[:id]
62
+ # memoize
63
+ @value ||= proc do |object|
64
+ validate_join_type!(value_by_name_proc(join_type).call(object))
65
+ # If it's a join field and it has join_id, the value is compound and contains
66
+ # both name (type) and id of the parent object
67
+ if value_by_name_proc(join_id).call(object).present?
68
+ {
69
+ name: value_by_name_proc(join_type).call(object), # parent type
70
+ parent: value_by_name_proc(join_id).call(object) # parent id
71
+ }
72
+ else
73
+ value_by_name_proc(join_type).call(object)
74
+ end
75
+ end
76
+ else
77
+ @value
78
+ end
79
+ end
80
+
48
81
  private
49
82
 
50
- def evaluate(objects)
51
- object = objects.first
83
+ def geo_point?
84
+ @options[:type].to_s == 'geo_point'
85
+ end
52
86
 
87
+ def join_field?
88
+ @options[:type].to_s == 'join'
89
+ end
90
+
91
+ def ignore_blank?
92
+ @options.fetch(:ignore_blank) { geo_point? }
93
+ end
94
+
95
+ def evaluate(objects)
53
96
  if value.is_a?(Proc)
54
- if value.arity.zero?
55
- object.instance_exec(&value)
56
- elsif value.arity < 0
57
- value.call(*object)
58
- else
59
- value.call(*objects.first(value.arity))
60
- end
97
+ value_by_proc(objects, value)
61
98
  else
62
- message = value.is_a?(Symbol) || value.is_a?(String) ? value.to_sym : name
99
+ value_by_name(objects, value)
100
+ end
101
+ end
102
+
103
+ def value_by_proc(objects, value)
104
+ object = objects.first
105
+ if value.arity.zero?
106
+ object.instance_exec(&value)
107
+ elsif value.arity.negative?
108
+ value.call(*object)
109
+ else
110
+ value.call(*objects.first(value.arity))
111
+ end
112
+ end
63
113
 
114
+ def value_by_name(objects, value)
115
+ object = objects.first
116
+ message = value.is_a?(Symbol) || value.is_a?(String) ? value.to_sym : name
117
+ value_by_name_proc(message).call(object)
118
+ end
119
+
120
+ def value_by_name_proc(message)
121
+ proc do |object|
64
122
  if object.is_a?(Hash)
65
123
  if object.key?(message)
66
124
  object[message]
@@ -73,6 +131,20 @@ module Chewy
73
131
  end
74
132
  end
75
133
 
134
+ def validate_join_type!(type)
135
+ return unless type
136
+ return if @allowed_relations.include?(type.to_sym)
137
+
138
+ raise Chewy::InvalidJoinFieldType.new(type, @name, options[:relations])
139
+ end
140
+
141
+ def find_allowed_relations(relations)
142
+ return [] unless relations
143
+ return relations unless relations.is_a?(Hash)
144
+
145
+ (relations.keys + relations.values).flatten.uniq
146
+ end
147
+
76
148
  def compose_children(value, *parent_objects)
77
149
  return unless value
78
150
 
@@ -1,20 +1,18 @@
1
1
  module Chewy
2
2
  module Fields
3
3
  class Root < Chewy::Fields::Base
4
- attr_reader :dynamic_templates
5
- attr_reader :id
6
- attr_reader :parent
7
- attr_reader :parent_id
4
+ attr_reader :dynamic_templates, :id
8
5
 
9
- def initialize(*args)
10
- super(*args)
6
+ def initialize(name, **options)
7
+ super(name, **options)
11
8
 
12
- @id = @options.delete(:id) || options.delete(:_id)
13
- @parent = @options.delete(:parent) || options.delete(:_parent)
14
- @parent_id = @options.delete(:parent_id)
15
9
  @value ||= -> { self }
16
10
  @dynamic_templates = []
17
- @options.delete(:type)
11
+ end
12
+
13
+ def update_options!(**options)
14
+ @id = options.fetch(:id, options.fetch(:_id, @id))
15
+ @options.merge!(options.except(:id, :_id, :type))
18
16
  end
19
17
 
20
18
  def mappings_hash
@@ -26,11 +24,10 @@ module Chewy
26
24
  mappings[name][:dynamic_templates].concat dynamic_templates
27
25
  end
28
26
 
29
- mappings[name][:_parent] = parent.is_a?(Hash) ? parent : {type: parent} if parent
30
- mappings
27
+ mappings[name]
31
28
  end
32
29
 
33
- def dynamic_template(*args)
30
+ ruby2_keywords def dynamic_template(*args)
34
31
  options = args.extract_options!.deep_symbolize_keys
35
32
  if args.first
36
33
  template_name = :"template_#{dynamic_templates.count.next}"
@@ -51,13 +48,9 @@ module Chewy
51
48
  end
52
49
  end
53
50
 
54
- def compose_parent(object)
55
- return unless parent_id
56
- parent_id.arity.zero? ? object.instance_exec(&parent_id) : parent_id.call(object)
57
- end
58
-
59
51
  def compose_id(object)
60
52
  return unless id
53
+
61
54
  id.arity.zero? ? object.instance_exec(&id) : id.call(object)
62
55
  end
63
56
 
@@ -66,7 +59,8 @@ module Chewy
66
59
  # @param object [Object] a base object for composition
67
60
  # @param crutches [Object] any object that will be passed to every field value proc as a last argument
68
61
  # @param fields [Array<Symbol>] a list of fields to compose, every field will be composed if empty
69
- # @return [Hash] JSON-ready heash with stringifyed keys
62
+ # @return [Hash] JSON-ready hash with stringified keys
63
+ #
70
64
  def compose(object, crutches = nil, fields: [])
71
65
  result = evaluate([object, crutches])
72
66
 
@@ -81,9 +75,9 @@ module Chewy
81
75
  memo.merge!(field.compose(result, crutches) || {})
82
76
  end.as_json
83
77
  elsif fields.present?
84
- result.as_json(only: fields)
78
+ result.as_json(only: fields, root: false)
85
79
  else
86
- result.as_json
80
+ result.as_json(root: false)
87
81
  end
88
82
  end
89
83