chewy 6.0.0 → 7.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/CODEOWNERS +1 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +39 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +20 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.github/dependabot.yml +42 -0
- data/.github/workflows/ruby.yml +60 -0
- data/.rubocop.yml +16 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +396 -105
- data/CODE_OF_CONDUCT.md +14 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +4 -10
- data/Guardfile +3 -1
- data/README.md +497 -275
- data/chewy.gemspec +5 -20
- data/gemfiles/base.gemfile +12 -0
- data/gemfiles/rails.6.1.activerecord.gemfile +10 -15
- data/gemfiles/rails.7.0.activerecord.gemfile +14 -0
- data/gemfiles/rails.7.1.activerecord.gemfile +14 -0
- data/lib/chewy/config.rb +60 -52
- data/lib/chewy/elastic_client.rb +31 -0
- data/lib/chewy/errors.rb +7 -10
- data/lib/chewy/fields/base.rb +79 -13
- data/lib/chewy/fields/root.rb +4 -14
- data/lib/chewy/index/actions.rb +54 -37
- data/lib/chewy/{type → index}/adapter/active_record.rb +30 -6
- data/lib/chewy/{type → index}/adapter/base.rb +2 -3
- data/lib/chewy/{type → index}/adapter/object.rb +27 -31
- data/lib/chewy/{type → index}/adapter/orm.rb +17 -18
- data/lib/chewy/index/aliases.rb +14 -5
- data/lib/chewy/index/crutch.rb +40 -0
- data/lib/chewy/index/import/bulk_builder.rb +311 -0
- data/lib/chewy/{type → index}/import/bulk_request.rb +6 -7
- data/lib/chewy/{type → index}/import/journal_builder.rb +11 -12
- data/lib/chewy/{type → index}/import/routine.rb +18 -17
- data/lib/chewy/{type → index}/import.rb +76 -32
- data/lib/chewy/{type → index}/mapping.rb +29 -34
- data/lib/chewy/index/observe/active_record_methods.rb +87 -0
- data/lib/chewy/index/observe/callback.rb +34 -0
- data/lib/chewy/index/observe.rb +17 -0
- data/lib/chewy/index/specification.rb +1 -0
- data/lib/chewy/{type → index}/syncer.rb +59 -59
- data/lib/chewy/{type → index}/witchcraft.rb +11 -7
- data/lib/chewy/{type → index}/wrapper.rb +2 -2
- data/lib/chewy/index.rb +67 -94
- data/lib/chewy/journal.rb +25 -14
- data/lib/chewy/log_subscriber.rb +5 -1
- data/lib/chewy/minitest/helpers.rb +86 -13
- data/lib/chewy/minitest/search_index_receiver.rb +24 -26
- data/lib/chewy/railtie.rb +6 -20
- data/lib/chewy/rake_helper.rb +169 -113
- data/lib/chewy/rspec/build_query.rb +12 -0
- data/lib/chewy/rspec/helpers.rb +55 -0
- data/lib/chewy/rspec/update_index.rb +55 -44
- data/lib/chewy/rspec.rb +2 -0
- data/lib/chewy/runtime/version.rb +1 -1
- data/lib/chewy/runtime.rb +1 -1
- data/lib/chewy/search/loader.rb +19 -41
- data/lib/chewy/search/parameters/collapse.rb +16 -0
- data/lib/chewy/search/parameters/concerns/query_storage.rb +2 -2
- data/lib/chewy/search/parameters/ignore_unavailable.rb +27 -0
- data/lib/chewy/search/parameters/indices.rb +13 -58
- data/lib/chewy/search/parameters/knn.rb +16 -0
- data/lib/chewy/search/parameters/order.rb +6 -19
- data/lib/chewy/search/parameters/source.rb +5 -1
- data/lib/chewy/search/parameters/storage.rb +1 -1
- data/lib/chewy/search/parameters/track_total_hits.rb +16 -0
- data/lib/chewy/search/parameters.rb +6 -4
- data/lib/chewy/search/query_proxy.rb +9 -2
- data/lib/chewy/search/request.rb +169 -134
- data/lib/chewy/search/response.rb +5 -5
- data/lib/chewy/search/scoping.rb +7 -8
- data/lib/chewy/search/scrolling.rb +13 -13
- data/lib/chewy/search.rb +9 -19
- data/lib/chewy/stash.rb +19 -30
- data/lib/chewy/strategy/active_job.rb +1 -1
- data/lib/chewy/strategy/atomic_no_refresh.rb +18 -0
- data/lib/chewy/strategy/base.rb +10 -0
- data/lib/chewy/strategy/delayed_sidekiq/scheduler.rb +168 -0
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +76 -0
- data/lib/chewy/strategy/delayed_sidekiq.rb +30 -0
- data/lib/chewy/strategy/lazy_sidekiq.rb +64 -0
- data/lib/chewy/strategy/sidekiq.rb +2 -1
- data/lib/chewy/strategy.rb +6 -19
- data/lib/chewy/version.rb +1 -1
- data/lib/chewy.rb +39 -86
- data/lib/generators/chewy/install_generator.rb +1 -1
- data/lib/tasks/chewy.rake +36 -32
- data/migration_guide.md +46 -8
- data/spec/chewy/config_spec.rb +16 -41
- data/spec/chewy/elastic_client_spec.rb +26 -0
- data/spec/chewy/fields/base_spec.rb +432 -147
- data/spec/chewy/fields/root_spec.rb +20 -28
- data/spec/chewy/fields/time_fields_spec.rb +5 -5
- data/spec/chewy/index/actions_spec.rb +368 -59
- data/spec/chewy/{type → index}/adapter/active_record_spec.rb +156 -40
- data/spec/chewy/{type → index}/adapter/object_spec.rb +21 -6
- data/spec/chewy/index/aliases_spec.rb +3 -3
- data/spec/chewy/index/import/bulk_builder_spec.rb +494 -0
- data/spec/chewy/{type → index}/import/bulk_request_spec.rb +5 -12
- data/spec/chewy/{type → index}/import/journal_builder_spec.rb +9 -19
- data/spec/chewy/{type → index}/import/routine_spec.rb +19 -19
- data/spec/chewy/{type → index}/import_spec.rb +164 -98
- data/spec/chewy/index/mapping_spec.rb +135 -0
- data/spec/chewy/index/observe/active_record_methods_spec.rb +68 -0
- data/spec/chewy/index/observe/callback_spec.rb +139 -0
- data/spec/chewy/index/observe_spec.rb +143 -0
- data/spec/chewy/index/settings_spec.rb +3 -1
- data/spec/chewy/index/specification_spec.rb +20 -30
- data/spec/chewy/{type → index}/syncer_spec.rb +14 -19
- data/spec/chewy/{type → index}/witchcraft_spec.rb +20 -22
- data/spec/chewy/index/wrapper_spec.rb +100 -0
- data/spec/chewy/index_spec.rb +60 -105
- data/spec/chewy/journal_spec.rb +25 -74
- data/spec/chewy/minitest/helpers_spec.rb +123 -15
- data/spec/chewy/minitest/search_index_receiver_spec.rb +28 -30
- data/spec/chewy/multi_search_spec.rb +4 -5
- data/spec/chewy/rake_helper_spec.rb +315 -55
- data/spec/chewy/rspec/build_query_spec.rb +34 -0
- data/spec/chewy/rspec/helpers_spec.rb +61 -0
- data/spec/chewy/rspec/update_index_spec.rb +74 -71
- data/spec/chewy/runtime_spec.rb +2 -2
- data/spec/chewy/search/loader_spec.rb +19 -53
- data/spec/chewy/search/pagination/kaminari_examples.rb +4 -6
- data/spec/chewy/search/pagination/kaminari_spec.rb +2 -2
- data/spec/chewy/search/parameters/collapse_spec.rb +5 -0
- data/spec/chewy/search/parameters/ignore_unavailable_spec.rb +67 -0
- data/spec/chewy/search/parameters/indices_spec.rb +26 -117
- data/spec/chewy/search/parameters/knn_spec.rb +5 -0
- data/spec/chewy/search/parameters/order_spec.rb +18 -11
- data/spec/chewy/search/parameters/query_storage_examples.rb +67 -21
- data/spec/chewy/search/parameters/search_after_spec.rb +4 -1
- data/spec/chewy/search/parameters/source_spec.rb +8 -2
- data/spec/chewy/search/parameters/track_total_hits_spec.rb +5 -0
- data/spec/chewy/search/parameters_spec.rb +18 -4
- data/spec/chewy/search/query_proxy_spec.rb +68 -17
- data/spec/chewy/search/request_spec.rb +292 -110
- data/spec/chewy/search/response_spec.rb +12 -12
- data/spec/chewy/search/scrolling_spec.rb +10 -17
- data/spec/chewy/search_spec.rb +40 -34
- data/spec/chewy/stash_spec.rb +9 -21
- data/spec/chewy/strategy/active_job_spec.rb +16 -16
- data/spec/chewy/strategy/atomic_no_refresh_spec.rb +60 -0
- data/spec/chewy/strategy/atomic_spec.rb +9 -10
- data/spec/chewy/strategy/delayed_sidekiq_spec.rb +208 -0
- data/spec/chewy/strategy/lazy_sidekiq_spec.rb +214 -0
- data/spec/chewy/strategy/sidekiq_spec.rb +12 -12
- data/spec/chewy/strategy_spec.rb +19 -15
- data/spec/chewy_spec.rb +24 -107
- data/spec/spec_helper.rb +3 -22
- data/spec/support/active_record.rb +25 -7
- metadata +78 -339
- data/.circleci/config.yml +0 -240
- data/Appraisals +0 -81
- data/gemfiles/rails.5.2.activerecord.gemfile +0 -17
- data/gemfiles/rails.5.2.mongoid.6.4.gemfile +0 -17
- data/gemfiles/rails.6.0.activerecord.gemfile +0 -17
- data/gemfiles/sequel.4.45.gemfile +0 -11
- data/lib/chewy/backports/deep_dup.rb +0 -46
- data/lib/chewy/backports/duplicable.rb +0 -91
- data/lib/chewy/search/pagination/will_paginate.rb +0 -43
- data/lib/chewy/search/parameters/types.rb +0 -20
- data/lib/chewy/strategy/resque.rb +0 -27
- data/lib/chewy/strategy/shoryuken.rb +0 -40
- data/lib/chewy/type/actions.rb +0 -43
- data/lib/chewy/type/adapter/mongoid.rb +0 -67
- data/lib/chewy/type/adapter/sequel.rb +0 -93
- data/lib/chewy/type/crutch.rb +0 -32
- data/lib/chewy/type/import/bulk_builder.rb +0 -122
- data/lib/chewy/type/observe.rb +0 -82
- data/lib/chewy/type.rb +0 -120
- data/lib/sequel/plugins/chewy_observe.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_examples.rb +0 -63
- data/spec/chewy/search/pagination/will_paginate_spec.rb +0 -23
- data/spec/chewy/search/parameters/types_spec.rb +0 -5
- data/spec/chewy/strategy/resque_spec.rb +0 -46
- data/spec/chewy/strategy/shoryuken_spec.rb +0 -70
- data/spec/chewy/type/actions_spec.rb +0 -50
- data/spec/chewy/type/adapter/mongoid_spec.rb +0 -372
- data/spec/chewy/type/adapter/sequel_spec.rb +0 -472
- data/spec/chewy/type/import/bulk_builder_spec.rb +0 -194
- data/spec/chewy/type/mapping_spec.rb +0 -175
- data/spec/chewy/type/observe_spec.rb +0 -137
- data/spec/chewy/type/wrapper_spec.rb +0 -100
- data/spec/chewy/type_spec.rb +0 -55
- data/spec/support/mongoid.rb +0 -93
- data/spec/support/sequel.rb +0 -80
data/chewy.gemspec
CHANGED
@@ -1,8 +1,8 @@
|
|
1
|
-
lib = File.expand_path('
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
3
|
require 'chewy/version'
|
4
4
|
|
5
|
-
Gem::Specification.new do |spec|
|
5
|
+
Gem::Specification.new do |spec|
|
6
6
|
spec.name = 'chewy'
|
7
7
|
spec.version = Chewy::VERSION
|
8
8
|
spec.authors = ['Toptal, LLC', 'pyromaniac']
|
@@ -14,25 +14,10 @@ Gem::Specification.new do |spec| # rubocop:disable BlockLength
|
|
14
14
|
|
15
15
|
spec.files = `git ls-files`.split($RS)
|
16
16
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
17
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
18
17
|
spec.require_paths = ['lib']
|
19
18
|
|
20
|
-
spec.
|
21
|
-
spec.
|
22
|
-
spec.add_development_dependency 'elasticsearch-extensions'
|
23
|
-
spec.add_development_dependency 'rake'
|
24
|
-
spec.add_development_dependency 'resque_spec'
|
25
|
-
spec.add_development_dependency 'rspec', '>= 3.7.0'
|
26
|
-
spec.add_development_dependency 'rspec-collection_matchers'
|
27
|
-
spec.add_development_dependency 'rspec-its'
|
28
|
-
spec.add_development_dependency 'rubocop', '0.52.1'
|
29
|
-
spec.add_development_dependency 'sqlite3'
|
30
|
-
spec.add_development_dependency 'timecop'
|
31
|
-
|
32
|
-
spec.add_development_dependency 'method_source'
|
33
|
-
spec.add_development_dependency 'unparser'
|
34
|
-
|
35
|
-
spec.add_dependency 'activesupport', '>= 5.2'
|
36
|
-
spec.add_dependency 'elasticsearch', '>= 6.3.0'
|
19
|
+
spec.add_dependency 'activesupport', '>= 5.2' # Remove with major version bump, 8.x
|
20
|
+
spec.add_dependency 'elasticsearch', '>= 7.14.0', '< 8'
|
37
21
|
spec.add_dependency 'elasticsearch-dsl'
|
22
|
+
spec.metadata['rubygems_mfa_required'] = 'true'
|
38
23
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
gem 'database_cleaner'
|
2
|
+
gem 'elasticsearch-extensions'
|
3
|
+
gem 'method_source'
|
4
|
+
gem 'rake'
|
5
|
+
gem 'redis', require: false
|
6
|
+
gem 'rspec', '>= 3.7.0'
|
7
|
+
gem 'rspec-collection_matchers'
|
8
|
+
gem 'rspec-its'
|
9
|
+
gem 'rubocop', '1.63.4'
|
10
|
+
gem 'sqlite3', '~> 1.4'
|
11
|
+
gem 'timecop'
|
12
|
+
gem 'unparser'
|
@@ -1,19 +1,14 @@
|
|
1
|
-
|
1
|
+
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
gem
|
6
|
-
gem
|
7
|
-
gem
|
8
|
-
gem "resque", require: false
|
9
|
-
gem "shoryuken", require: false
|
10
|
-
gem "aws-sdk-sqs", require: false
|
11
|
-
gem "sidekiq", require: false
|
12
|
-
gem "kaminari-core", "~> 1.1.0", require: false
|
13
|
-
gem "will_paginate", require: false
|
14
|
-
gem "parallel", require: false
|
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
|
15
8
|
gem 'rspec_junit_formatter', '~> 0.4.1'
|
9
|
+
gem 'sidekiq', require: false
|
16
10
|
|
17
|
-
gem 'rexml'
|
11
|
+
gem 'rexml'
|
18
12
|
|
19
|
-
gemspec path:
|
13
|
+
gemspec path: '../'
|
14
|
+
eval_gemfile 'base.gemfile'
|
@@ -0,0 +1,14 @@
|
|
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'
|
12
|
+
|
13
|
+
gemspec path: '../'
|
14
|
+
eval_gemfile 'base.gemfile'
|
@@ -0,0 +1,14 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'activejob', '~> 7.1.0'
|
4
|
+
gem 'activerecord', '~> 7.1.0'
|
5
|
+
gem 'activesupport', '~> 7.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'
|
12
|
+
|
13
|
+
gemspec path: '../'
|
14
|
+
eval_gemfile 'base.gemfile'
|
data/lib/chewy/config.rb
CHANGED
@@ -3,43 +3,51 @@ module Chewy
|
|
3
3
|
include Singleton
|
4
4
|
|
5
5
|
attr_accessor :settings, :logger,
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
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
|
+
# Callback called on each search request to be done into ES
|
43
|
+
:before_es_request_filter,
|
44
|
+
# Behavior when import scope for index includes order, offset or limit.
|
45
|
+
# Can be :ignore, :warn, :raise. Defaults to :warn
|
46
|
+
:import_scope_cleanup_behavior
|
39
47
|
|
40
48
|
attr_reader :transport_logger, :transport_tracer,
|
41
|
-
|
42
|
-
|
49
|
+
# Chewy search request DSL base class, used by every index.
|
50
|
+
:search_class
|
43
51
|
|
44
52
|
def self.delegated
|
45
53
|
public_instance_methods - superclass.public_instance_methods - Singleton.public_instance_methods
|
@@ -49,6 +57,7 @@ module Chewy
|
|
49
57
|
@settings = {}
|
50
58
|
@root_strategy = :base
|
51
59
|
@request_strategy = :atomic
|
60
|
+
@console_strategy = :urgent
|
52
61
|
@use_after_commit_callbacks = true
|
53
62
|
@reset_disable_refresh_interval = false
|
54
63
|
@reset_no_replicas = false
|
@@ -56,16 +65,17 @@ module Chewy
|
|
56
65
|
@indices_path = 'app/chewy'
|
57
66
|
@default_root_options = {}
|
58
67
|
@default_field_type = 'text'.freeze
|
68
|
+
@import_scope_cleanup_behavior = :warn
|
59
69
|
@search_class = build_search_class(Chewy::Search::Request)
|
60
70
|
end
|
61
71
|
|
62
72
|
def transport_logger=(logger)
|
63
|
-
Chewy.client.transport.logger = logger
|
73
|
+
Chewy.client.transport.transport.logger = logger
|
64
74
|
@transport_logger = logger
|
65
75
|
end
|
66
76
|
|
67
77
|
def transport_tracer=(tracer)
|
68
|
-
Chewy.client.transport.tracer = tracer
|
78
|
+
Chewy.client.transport.transport.tracer = tracer
|
69
79
|
@transport_tracer = tracer
|
70
80
|
end
|
71
81
|
|
@@ -123,26 +133,24 @@ module Chewy
|
|
123
133
|
private
|
124
134
|
|
125
135
|
def yaml_settings
|
126
|
-
@yaml_settings ||=
|
127
|
-
|
128
|
-
file = Rails.root.join('config', 'chewy.yml')
|
136
|
+
@yaml_settings ||= build_yaml_settings || {}
|
137
|
+
end
|
129
138
|
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
139
|
+
def build_yaml_settings
|
140
|
+
return unless defined?(Rails::VERSION)
|
141
|
+
|
142
|
+
file = Rails.root.join('config', 'chewy.yml')
|
143
|
+
|
144
|
+
return unless File.exist?(file)
|
145
|
+
|
146
|
+
yaml = ERB.new(File.read(file)).result
|
147
|
+
hash = YAML.unsafe_load(yaml)
|
148
|
+
hash[Rails.env].try(:deep_symbolize_keys) if hash
|
137
149
|
end
|
138
150
|
|
139
151
|
def build_search_class(base)
|
140
152
|
Class.new(base).tap do |search_class|
|
141
|
-
if defined?(::Kaminari)
|
142
|
-
search_class.send :include, Chewy::Search::Pagination::Kaminari
|
143
|
-
elsif defined?(::WillPaginate)
|
144
|
-
search_class.send :include, Chewy::Search::Pagination::WillPaginate
|
145
|
-
end
|
153
|
+
search_class.send :include, Chewy::Search::Pagination::Kaminari if defined?(::Kaminari)
|
146
154
|
end
|
147
155
|
end
|
148
156
|
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module Chewy
|
2
|
+
# Replacement for Chewy.client
|
3
|
+
class ElasticClient
|
4
|
+
def self.build_es_client(configuration = Chewy.configuration)
|
5
|
+
client_configuration = configuration.deep_dup
|
6
|
+
client_configuration.delete(:prefix) # used by Chewy, not relevant to Elasticsearch::Client
|
7
|
+
block = client_configuration[:transport_options].try(:delete, :proc)
|
8
|
+
::Elasticsearch::Client.new(client_configuration, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize(elastic_client = self.class.build_es_client)
|
12
|
+
@elastic_client = elastic_client
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def method_missing(name, *args, **kwargs, &block)
|
18
|
+
inspect_payload(name, args, kwargs)
|
19
|
+
|
20
|
+
@elastic_client.__send__(name, *args, **kwargs, &block)
|
21
|
+
end
|
22
|
+
|
23
|
+
def respond_to_missing?(name, _include_private = false)
|
24
|
+
@elastic_client.respond_to?(name) || super
|
25
|
+
end
|
26
|
+
|
27
|
+
def inspect_payload(name, args, kwargs)
|
28
|
+
Chewy.config.before_es_request_filter&.call(name, args, kwargs)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/chewy/errors.rb
CHANGED
@@ -5,15 +5,9 @@ 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
|
-
super
|
10
|
+
super(<<-MESSAGE)
|
17
11
|
Index update strategy is undefined for current context.
|
18
12
|
Please wrap your code with `Chewy.strategy(:strategy_name) block.`
|
19
13
|
MESSAGE
|
@@ -33,13 +27,16 @@ module Chewy
|
|
33
27
|
message << " on #{documents.count} documents: #{documents}\n"
|
34
28
|
end
|
35
29
|
end
|
36
|
-
super
|
30
|
+
super(message)
|
37
31
|
end
|
38
32
|
end
|
39
33
|
|
40
|
-
class
|
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
|
41
38
|
end
|
42
39
|
|
43
|
-
class
|
40
|
+
class ImportScopeCleanupError < Error
|
44
41
|
end
|
45
42
|
end
|
data/lib/chewy/fields/base.rb
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
module Chewy
|
2
2
|
module Fields
|
3
3
|
class Base
|
4
|
-
attr_reader :name, :
|
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
7
|
def initialize(name, value: nil, **options)
|
8
8
|
@name = name.to_sym
|
@@ -10,9 +10,11 @@ module Chewy
|
|
10
10
|
update_options!(**options)
|
11
11
|
@value = value
|
12
12
|
@children = []
|
13
|
+
@allowed_relations = find_allowed_relations(options[:relations]) # for join fields
|
13
14
|
end
|
14
15
|
|
15
16
|
def update_options!(**options)
|
17
|
+
@join_options = options.delete(:join) || {}
|
16
18
|
@options = options
|
17
19
|
end
|
18
20
|
|
@@ -31,7 +33,7 @@ module Chewy
|
|
31
33
|
else
|
32
34
|
{}
|
33
35
|
end
|
34
|
-
mapping.reverse_merge!(options)
|
36
|
+
mapping.reverse_merge!(options.except(:ignore_blank))
|
35
37
|
mapping.reverse_merge!(type: (children.present? ? 'object' : Chewy.default_field_type))
|
36
38
|
|
37
39
|
{name => mapping}
|
@@ -40,6 +42,8 @@ module Chewy
|
|
40
42
|
def compose(*objects)
|
41
43
|
result = evaluate(objects)
|
42
44
|
|
45
|
+
return {} if result.blank? && ignore_blank?
|
46
|
+
|
43
47
|
if children.present? && !multi_field?
|
44
48
|
result = if result.respond_to?(:to_ary)
|
45
49
|
result.to_ary.map { |item| compose_children(item, *objects) }
|
@@ -51,22 +55,70 @@ module Chewy
|
|
51
55
|
{name => result}
|
52
56
|
end
|
53
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
|
+
|
54
81
|
private
|
55
82
|
|
56
|
-
def
|
57
|
-
|
83
|
+
def geo_point?
|
84
|
+
@options[:type].to_s == 'geo_point'
|
85
|
+
end
|
86
|
+
|
87
|
+
def join_field?
|
88
|
+
@options[:type].to_s == 'join'
|
89
|
+
end
|
58
90
|
|
91
|
+
def ignore_blank?
|
92
|
+
@options.fetch(:ignore_blank) { geo_point? }
|
93
|
+
end
|
94
|
+
|
95
|
+
def evaluate(objects)
|
59
96
|
if value.is_a?(Proc)
|
60
|
-
|
61
|
-
object.instance_exec(&value)
|
62
|
-
elsif value.arity < 0
|
63
|
-
value.call(*object)
|
64
|
-
else
|
65
|
-
value.call(*objects.first(value.arity))
|
66
|
-
end
|
97
|
+
value_by_proc(objects, value)
|
67
98
|
else
|
68
|
-
|
99
|
+
value_by_name(objects, value)
|
100
|
+
end
|
101
|
+
end
|
69
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
|
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|
|
70
122
|
if object.is_a?(Hash)
|
71
123
|
if object.key?(message)
|
72
124
|
object[message]
|
@@ -79,6 +131,20 @@ module Chewy
|
|
79
131
|
end
|
80
132
|
end
|
81
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
|
+
|
82
148
|
def compose_children(value, *parent_objects)
|
83
149
|
return unless value
|
84
150
|
|
data/lib/chewy/fields/root.rb
CHANGED
@@ -1,10 +1,7 @@
|
|
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
6
|
def initialize(name, **options)
|
10
7
|
super(name, **options)
|
@@ -15,9 +12,7 @@ module Chewy
|
|
15
12
|
|
16
13
|
def update_options!(**options)
|
17
14
|
@id = options.fetch(:id, options.fetch(:_id, @id))
|
18
|
-
@
|
19
|
-
@parent_id = options.fetch(:parent_id, @parent_id)
|
20
|
-
@options.merge!(options.except(:id, :_id, :parent, :_parent, :parent_id, :type))
|
15
|
+
@options.merge!(options.except(:id, :_id, :type))
|
21
16
|
end
|
22
17
|
|
23
18
|
def mappings_hash
|
@@ -29,8 +24,7 @@ module Chewy
|
|
29
24
|
mappings[name][:dynamic_templates].concat dynamic_templates
|
30
25
|
end
|
31
26
|
|
32
|
-
mappings[name]
|
33
|
-
mappings
|
27
|
+
mappings[name]
|
34
28
|
end
|
35
29
|
|
36
30
|
def dynamic_template(*args)
|
@@ -54,13 +48,9 @@ module Chewy
|
|
54
48
|
end
|
55
49
|
end
|
56
50
|
|
57
|
-
def compose_parent(object)
|
58
|
-
return unless parent_id
|
59
|
-
parent_id.arity.zero? ? object.instance_exec(&parent_id) : parent_id.call(object)
|
60
|
-
end
|
61
|
-
|
62
51
|
def compose_id(object)
|
63
52
|
return unless id
|
53
|
+
|
64
54
|
id.arity.zero? ? object.instance_exec(&id) : id.call(object)
|
65
55
|
end
|
66
56
|
|
data/lib/chewy/index/actions.rb
CHANGED
@@ -59,9 +59,7 @@ module Chewy
|
|
59
59
|
|
60
60
|
body = specification_hash
|
61
61
|
body[:aliases] = {general_name => {}} if options[:alias] && suffixed_name != general_name
|
62
|
-
|
63
|
-
args[:include_type_name] = true if Runtime.version >= '6.7.0'
|
64
|
-
result = client.indices.create(**args)
|
62
|
+
result = client.indices.create(index: suffixed_name, body: body)
|
65
63
|
|
66
64
|
Chewy.wait_for_status if result
|
67
65
|
result
|
@@ -131,37 +129,6 @@ module Chewy
|
|
131
129
|
create! suffix
|
132
130
|
end
|
133
131
|
|
134
|
-
# Perform import operation for every defined type
|
135
|
-
#
|
136
|
-
# UsersIndex.import # imports default data for every index type
|
137
|
-
# UsersIndex.import user: User.active # imports specified objects for user type and default data for other types
|
138
|
-
# UsersIndex.import refresh: false # to disable index refreshing after import
|
139
|
-
# UsersIndex.import suffix: Time.now.to_i # imports data to index with specified suffix if such is exists
|
140
|
-
# UsersIndex.import batch_size: 300 # import batch size
|
141
|
-
#
|
142
|
-
# See [import.rb](lib/chewy/type/import.rb) for more details.
|
143
|
-
#
|
144
|
-
%i[import import!].each do |method|
|
145
|
-
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
146
|
-
def #{method}(*args)
|
147
|
-
return true if args.first.blank? && !args.first.nil?
|
148
|
-
|
149
|
-
options = args.extract_options!
|
150
|
-
if args.one? && type_names.one?
|
151
|
-
objects = {type_names.first.to_sym => args.first}
|
152
|
-
elsif args.one?
|
153
|
-
fail ArgumentError, "Please pass objects for `#{method}` as a hash with type names"
|
154
|
-
else
|
155
|
-
objects = options.reject { |k, v| !type_names.map(&:to_sym).include?(k) }
|
156
|
-
end
|
157
|
-
types.map do |type|
|
158
|
-
args = [objects[type.type_name.to_sym], options.dup].reject(&:blank?)
|
159
|
-
type.#{method} *args
|
160
|
-
end.all?
|
161
|
-
end
|
162
|
-
METHOD
|
163
|
-
end
|
164
|
-
|
165
132
|
# Deletes, creates and imports data to the index. Returns the
|
166
133
|
# import result. If index name suffix is passed as the first
|
167
134
|
# argument - performs zero-downtime index resetting.
|
@@ -182,14 +149,18 @@ module Chewy
|
|
182
149
|
def reset!(suffix = nil, apply_journal: true, journal: false, **import_options)
|
183
150
|
result = if suffix.present?
|
184
151
|
start_time = Time.now
|
185
|
-
indexes = self.indexes
|
152
|
+
indexes = self.indexes - [index_name]
|
186
153
|
create! suffix, alias: false
|
187
154
|
|
188
155
|
general_name = index_name
|
189
156
|
suffixed_name = index_name(suffix: suffix)
|
190
157
|
|
191
158
|
optimize_index_settings suffixed_name
|
192
|
-
result = import
|
159
|
+
result = import(**import_options.merge(
|
160
|
+
suffix: suffix,
|
161
|
+
journal: journal,
|
162
|
+
refresh: !Chewy.reset_disable_refresh_interval
|
163
|
+
))
|
193
164
|
original_index_settings suffixed_name
|
194
165
|
|
195
166
|
delete if indexes.blank?
|
@@ -205,12 +176,13 @@ module Chewy
|
|
205
176
|
result
|
206
177
|
else
|
207
178
|
purge!
|
208
|
-
import
|
179
|
+
import(**import_options.merge(journal: journal))
|
209
180
|
end
|
210
181
|
|
211
182
|
specification.lock!
|
212
183
|
result
|
213
184
|
end
|
185
|
+
alias_method :reset, :reset!
|
214
186
|
|
215
187
|
# A {Chewy::Journal} instance for the particular index
|
216
188
|
#
|
@@ -219,6 +191,50 @@ module Chewy
|
|
219
191
|
@journal ||= Chewy::Journal.new(self)
|
220
192
|
end
|
221
193
|
|
194
|
+
def clear_cache(args = {index: index_name})
|
195
|
+
client.indices.clear_cache(args)
|
196
|
+
end
|
197
|
+
|
198
|
+
def reindex(source: index_name, dest: index_name)
|
199
|
+
client.reindex(
|
200
|
+
{
|
201
|
+
body:
|
202
|
+
{
|
203
|
+
source: {index: source},
|
204
|
+
dest: {index: dest}
|
205
|
+
}
|
206
|
+
}
|
207
|
+
)
|
208
|
+
end
|
209
|
+
|
210
|
+
# Adds new fields to an existing data stream or index.
|
211
|
+
# Change the search settings of existing fields.
|
212
|
+
#
|
213
|
+
# @example
|
214
|
+
# Chewy.client.update_mapping('cities', {properties: {new_field: {type: :text}}})
|
215
|
+
#
|
216
|
+
def update_mapping(name = index_name, body = root.mappings_hash)
|
217
|
+
client.indices.put_mapping(
|
218
|
+
index: name,
|
219
|
+
body: body
|
220
|
+
)['acknowledged']
|
221
|
+
end
|
222
|
+
|
223
|
+
# Performs missing and outdated objects synchronization for the current index.
|
224
|
+
#
|
225
|
+
# @example
|
226
|
+
# UsersIndex.sync
|
227
|
+
#
|
228
|
+
# @see Chewy::Index::Syncer
|
229
|
+
# @param parallel [true, Integer, Hash] options for parallel execution or the number of processes
|
230
|
+
# @return [Hash{Symbol, Object}, nil] a number of missing and outdated documents re-indexed and their ids,
|
231
|
+
# nil in case of errors
|
232
|
+
def sync(parallel: nil)
|
233
|
+
syncer = Syncer.new(self, parallel: parallel)
|
234
|
+
count = syncer.perform
|
235
|
+
{count: count, missing: syncer.missing_ids, outdated: syncer.outdated_ids} if count
|
236
|
+
end
|
237
|
+
|
222
238
|
private
|
223
239
|
|
224
240
|
def optimize_index_settings(index_name)
|
@@ -244,6 +260,7 @@ module Chewy
|
|
244
260
|
|
245
261
|
def index_settings(setting_name)
|
246
262
|
return {} unless settings_hash.key?(:settings) && settings_hash[:settings].key?(:index)
|
263
|
+
|
247
264
|
settings_hash[:settings][:index].slice(setting_name)
|
248
265
|
end
|
249
266
|
end
|