chewy 6.0.0 → 7.5.1
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 +48 -0
- data/.rubocop.yml +16 -8
- data/.rubocop_todo.yml +110 -22
- data/CHANGELOG.md +385 -105
- data/CODE_OF_CONDUCT.md +14 -0
- data/CONTRIBUTING.md +63 -0
- data/Gemfile +4 -10
- data/Guardfile +3 -1
- data/README.md +494 -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 +58 -50
- 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 +151 -0
- data/lib/chewy/strategy/delayed_sidekiq/worker.rb +52 -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 +14 -39
- 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 +202 -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
@@ -1,24 +1,22 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
# TODO: add more specs here later
|
4
|
-
describe Chewy::
|
4
|
+
describe Chewy::Index::Import::Routine do
|
5
5
|
before { Chewy.massacre }
|
6
6
|
before do
|
7
7
|
stub_index(:cities) do
|
8
|
-
|
9
|
-
|
10
|
-
field :object, type: 'object'
|
11
|
-
end
|
8
|
+
field :name
|
9
|
+
field :object, type: 'object'
|
12
10
|
end
|
13
11
|
CitiesIndex.create!
|
14
12
|
end
|
15
13
|
|
16
|
-
let(:index) { [double(id: 1, name: 'Name', object: {}), double(id: 2, name: 'Name', object: {})] }
|
17
|
-
let(:delete) { [double(id: 3, name: 'Name')] }
|
14
|
+
let(:index) { [double('city_1', id: 1, name: 'Name', object: {}), double('city_2', id: 2, name: 'Name', object: {})] }
|
15
|
+
let(:delete) { [double('city_3', id: 3, name: 'Name', object: {})] }
|
18
16
|
|
19
17
|
describe '#options' do
|
20
18
|
specify do
|
21
|
-
expect(described_class.new(CitiesIndex
|
19
|
+
expect(described_class.new(CitiesIndex).options).to eq(
|
22
20
|
journal: nil,
|
23
21
|
refresh: true,
|
24
22
|
update_failover: true,
|
@@ -29,7 +27,7 @@ describe Chewy::Type::Import::Routine do
|
|
29
27
|
|
30
28
|
specify do
|
31
29
|
expect(described_class.new(
|
32
|
-
CitiesIndex
|
30
|
+
CitiesIndex, batch_size: 100, bulk_size: 1.megabyte, refresh: false
|
33
31
|
).options).to eq(
|
34
32
|
journal: nil,
|
35
33
|
refresh: false,
|
@@ -43,7 +41,7 @@ describe Chewy::Type::Import::Routine do
|
|
43
41
|
context do
|
44
42
|
before { allow(Chewy).to receive_messages(configuration: Chewy.configuration.merge(journal: true)) }
|
45
43
|
specify do
|
46
|
-
expect(described_class.new(CitiesIndex
|
44
|
+
expect(described_class.new(CitiesIndex).options).to eq(
|
47
45
|
journal: true,
|
48
46
|
refresh: true,
|
49
47
|
update_failover: true,
|
@@ -55,24 +53,26 @@ describe Chewy::Type::Import::Routine do
|
|
55
53
|
|
56
54
|
specify do
|
57
55
|
expect(CitiesIndex.client).to receive(:bulk).with(hash_including(refresh: true))
|
58
|
-
described_class.new(CitiesIndex
|
56
|
+
described_class.new(CitiesIndex).process(index: index)
|
59
57
|
end
|
60
58
|
|
61
59
|
specify do
|
62
60
|
expect(CitiesIndex.client).to receive(:bulk).with(hash_including(refresh: false))
|
63
|
-
described_class.new(CitiesIndex
|
61
|
+
described_class.new(CitiesIndex, refresh: false).process(index: index)
|
64
62
|
end
|
65
63
|
end
|
66
64
|
|
67
65
|
describe '#parallel_options' do
|
68
|
-
specify { expect(described_class.new(CitiesIndex
|
69
|
-
specify { expect(described_class.new(CitiesIndex
|
70
|
-
specify { expect(described_class.new(CitiesIndex
|
71
|
-
specify
|
66
|
+
specify { expect(described_class.new(CitiesIndex).parallel_options).to be_nil }
|
67
|
+
specify { expect(described_class.new(CitiesIndex, parallel: true).parallel_options).to eq({}) }
|
68
|
+
specify { expect(described_class.new(CitiesIndex, parallel: 3).parallel_options).to eq(in_processes: 3) }
|
69
|
+
specify do
|
70
|
+
expect(described_class.new(CitiesIndex, parallel: {in_threads: 2}).parallel_options).to eq(in_threads: 2)
|
71
|
+
end
|
72
72
|
end
|
73
73
|
|
74
74
|
describe '#stats' do
|
75
|
-
subject { described_class.new(CitiesIndex
|
75
|
+
subject { described_class.new(CitiesIndex) }
|
76
76
|
|
77
77
|
specify { expect(subject.stats).to eq({}) }
|
78
78
|
specify do
|
@@ -92,8 +92,8 @@ describe Chewy::Type::Import::Routine do
|
|
92
92
|
end
|
93
93
|
|
94
94
|
describe '#errors' do
|
95
|
-
subject { described_class.new(CitiesIndex
|
96
|
-
let(:index) { [double(id: 1, name: 'Name', object: ''), double(id: 2, name: 'Name', object: {})] }
|
95
|
+
subject { described_class.new(CitiesIndex) }
|
96
|
+
let(:index) { [double('city_1', id: 1, name: 'Name', object: ''), double('city_2', id: 2, name: 'Name', object: {})] }
|
97
97
|
|
98
98
|
specify { expect(subject.errors).to eq([]) }
|
99
99
|
specify do
|
@@ -1,6 +1,6 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe Chewy::
|
3
|
+
describe Chewy::Index::Import do
|
4
4
|
before { Chewy.massacre }
|
5
5
|
|
6
6
|
before do
|
@@ -9,14 +9,13 @@ describe Chewy::Type::Import do
|
|
9
9
|
|
10
10
|
before do
|
11
11
|
stub_index(:cities) do
|
12
|
-
|
13
|
-
|
14
|
-
end
|
12
|
+
index_scope City
|
13
|
+
field :name
|
15
14
|
end
|
16
15
|
end
|
17
16
|
|
18
17
|
def imported_cities
|
19
|
-
CitiesIndex
|
18
|
+
CitiesIndex.all.map do |city|
|
20
19
|
city.attributes.except('_score', '_explanation')
|
21
20
|
end
|
22
21
|
end
|
@@ -37,13 +36,13 @@ describe Chewy::Type::Import do
|
|
37
36
|
specify 'lazy (default)' do
|
38
37
|
expect(CitiesIndex).to receive(:exists?).and_call_original
|
39
38
|
expect(CitiesIndex).to receive(:create!).and_call_original
|
40
|
-
CitiesIndex
|
39
|
+
CitiesIndex.import(dummy_city)
|
41
40
|
end
|
42
41
|
|
43
42
|
specify 'lazy without objects' do
|
44
43
|
expect(CitiesIndex).not_to receive(:exists?)
|
45
44
|
expect(CitiesIndex).not_to receive(:create!)
|
46
|
-
CitiesIndex
|
45
|
+
CitiesIndex.import([])
|
47
46
|
end
|
48
47
|
|
49
48
|
context 'skip' do
|
@@ -58,7 +57,20 @@ describe Chewy::Type::Import do
|
|
58
57
|
specify do
|
59
58
|
expect(CitiesIndex).not_to receive(:exists?)
|
60
59
|
expect(CitiesIndex).not_to receive(:create!)
|
61
|
-
CitiesIndex
|
60
|
+
CitiesIndex.import(dummy_city)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context 'skip journal creation on import' do
|
65
|
+
before do
|
66
|
+
Chewy::Stash::Journal.create!
|
67
|
+
Chewy.config.settings[:skip_journal_creation_on_import] = true
|
68
|
+
end
|
69
|
+
after { Chewy.config.settings[:skip_journal_creation_on_import] = nil }
|
70
|
+
|
71
|
+
specify do
|
72
|
+
expect(Chewy::Stash::Journal).not_to receive(:create!)
|
73
|
+
CitiesIndex.import(dummy_city, journal: true)
|
62
74
|
end
|
63
75
|
end
|
64
76
|
end
|
@@ -69,35 +81,36 @@ describe Chewy::Type::Import do
|
|
69
81
|
specify { expect(import(dummy_cities)).to eq(true) }
|
70
82
|
specify { expect(import(dummy_cities.map(&:id))).to eq(true) }
|
71
83
|
|
72
|
-
specify { expect { import([]) }.not_to update_index(CitiesIndex
|
73
|
-
specify { expect { import }.to update_index(CitiesIndex
|
74
|
-
specify { expect { import dummy_cities }.to update_index(CitiesIndex
|
75
|
-
specify { expect { import dummy_cities.map(&:id) }.to update_index(CitiesIndex
|
84
|
+
specify { expect { import([]) }.not_to update_index(CitiesIndex) }
|
85
|
+
specify { expect { import }.to update_index(CitiesIndex).and_reindex(dummy_cities) }
|
86
|
+
specify { expect { import dummy_cities }.to update_index(CitiesIndex).and_reindex(dummy_cities) }
|
87
|
+
specify { expect { import dummy_cities.map(&:id) }.to update_index(CitiesIndex).and_reindex(dummy_cities) }
|
76
88
|
|
77
89
|
describe 'criteria-driven importing' do
|
78
90
|
let(:names) { %w[name0 name1] }
|
79
91
|
|
80
|
-
context 'mongoid', :mongoid do
|
81
|
-
specify { expect { import(City.where(:name.in => names)) }.to update_index(CitiesIndex::City).and_reindex(dummy_cities.first(2)) }
|
82
|
-
specify { expect { import(City.where(:name.in => names).map(&:id)) }.to update_index(CitiesIndex::City).and_reindex(dummy_cities.first(2)) }
|
83
|
-
end
|
84
|
-
|
85
92
|
context 'active record', :active_record do
|
86
|
-
specify
|
87
|
-
|
93
|
+
specify do
|
94
|
+
expect { import(City.where(name: names)) }
|
95
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities.first(2))
|
96
|
+
end
|
97
|
+
specify do
|
98
|
+
expect { import(City.where(name: names).map(&:id)) }
|
99
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities.first(2))
|
100
|
+
end
|
88
101
|
end
|
89
102
|
end
|
90
103
|
|
91
104
|
specify do
|
92
105
|
dummy_cities.first.destroy
|
93
106
|
expect { import dummy_cities }
|
94
|
-
.to update_index(CitiesIndex
|
107
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities.from(1)).and_delete(dummy_cities.first)
|
95
108
|
end
|
96
109
|
|
97
110
|
specify do
|
98
111
|
dummy_cities.first.destroy
|
99
112
|
expect { import dummy_cities.map(&:id) }
|
100
|
-
.to update_index(CitiesIndex
|
113
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities.from(1)).and_delete(dummy_cities.first)
|
101
114
|
end
|
102
115
|
|
103
116
|
specify do
|
@@ -120,7 +133,10 @@ describe Chewy::Type::Import do
|
|
120
133
|
context ':bulk_size' do
|
121
134
|
let!(:dummy_cities) { Array.new(3) { |i| City.create(id: i + 1, name: "name#{i}" * 20) } }
|
122
135
|
|
123
|
-
specify
|
136
|
+
specify do
|
137
|
+
expect { import(dummy_cities, bulk_size: 1.2.kilobyte) }
|
138
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities)
|
139
|
+
end
|
124
140
|
|
125
141
|
context do
|
126
142
|
before { expect(Chewy.client).to receive(:bulk).exactly(3).times.and_call_original }
|
@@ -132,31 +148,29 @@ describe Chewy::Type::Import do
|
|
132
148
|
before do
|
133
149
|
names = %w[name0 name1]
|
134
150
|
|
135
|
-
criteria =
|
136
|
-
when :mongoid
|
137
|
-
{:name.in => names}
|
138
|
-
else
|
139
|
-
{name: names}
|
140
|
-
end
|
151
|
+
criteria = {name: names}
|
141
152
|
|
142
153
|
stub_index(:cities) do
|
143
|
-
|
144
|
-
|
145
|
-
end
|
154
|
+
index_scope City.where(criteria)
|
155
|
+
field :name
|
146
156
|
end
|
147
157
|
end
|
148
158
|
|
149
|
-
specify { expect { import }.to update_index(CitiesIndex
|
159
|
+
specify { expect { import }.to update_index(CitiesIndex).and_reindex(dummy_cities.first(2)) }
|
150
160
|
|
151
|
-
context '
|
161
|
+
context 'active record', :active_record do
|
152
162
|
specify do
|
153
|
-
expect { import City.where(
|
163
|
+
expect { import City.where(id: dummy_cities.first.id) }
|
164
|
+
.to update_index(CitiesIndex).and_reindex(dummy_cities.first).only
|
154
165
|
end
|
155
|
-
end
|
156
166
|
|
157
|
-
context 'active record', :active_record do
|
158
167
|
specify do
|
159
|
-
|
168
|
+
allow(CitiesIndex).to receive(:import_linear).and_return(double(present?: false))
|
169
|
+
allow(CitiesIndex).to receive(:import_parallel).and_return(double(present?: false))
|
170
|
+
|
171
|
+
expects_no_query(except: /SELECT\s+1\s+AS\s+one\s+FROM/) do
|
172
|
+
import City.where(id: dummy_cities.first.id)
|
173
|
+
end
|
160
174
|
end
|
161
175
|
end
|
162
176
|
end
|
@@ -166,28 +180,27 @@ describe Chewy::Type::Import do
|
|
166
180
|
payload = subscribe_notification
|
167
181
|
dummy_cities.first.destroy
|
168
182
|
import dummy_cities
|
169
|
-
expect(payload).to eq(
|
183
|
+
expect(payload).to eq(index: CitiesIndex, import: {delete: 1, index: 2})
|
170
184
|
end
|
171
185
|
|
172
186
|
specify do
|
173
187
|
payload = subscribe_notification
|
174
188
|
dummy_cities.first.destroy
|
175
189
|
import dummy_cities, batch_size: 2
|
176
|
-
expect(payload).to eq(
|
190
|
+
expect(payload).to eq(index: CitiesIndex, import: {delete: 1, index: 2})
|
177
191
|
end
|
178
192
|
|
179
193
|
specify do
|
180
194
|
payload = subscribe_notification
|
181
195
|
import dummy_cities, batch_size: 2
|
182
|
-
expect(payload).to eq(
|
196
|
+
expect(payload).to eq(index: CitiesIndex, import: {index: 3})
|
183
197
|
end
|
184
198
|
|
185
199
|
context do
|
186
200
|
before do
|
187
201
|
stub_index(:cities) do
|
188
|
-
|
189
|
-
|
190
|
-
end
|
202
|
+
index_scope City
|
203
|
+
field :name, type: 'object'
|
191
204
|
end
|
192
205
|
end
|
193
206
|
|
@@ -201,15 +214,15 @@ describe Chewy::Type::Import do
|
|
201
214
|
specify do
|
202
215
|
payload = subscribe_notification
|
203
216
|
import dummy_cities, batch_size: 2
|
204
|
-
expect(payload).to eq(
|
205
|
-
|
206
|
-
|
217
|
+
expect(payload).to eq(index: CitiesIndex,
|
218
|
+
errors: {index: {mapper_parsing_exception => %w[1 2 3]}},
|
219
|
+
import: {index: 3})
|
207
220
|
end
|
208
221
|
end
|
209
222
|
end
|
210
223
|
|
211
224
|
context 'fields' do
|
212
|
-
before { CitiesIndex
|
225
|
+
before { CitiesIndex.import!(dummy_cities.first(2)) }
|
213
226
|
|
214
227
|
context do
|
215
228
|
before { expect(Chewy.client).to receive(:bulk).twice.and_call_original }
|
@@ -217,7 +230,7 @@ describe Chewy::Type::Import do
|
|
217
230
|
end
|
218
231
|
|
219
232
|
context do
|
220
|
-
before { CitiesIndex
|
233
|
+
before { CitiesIndex.import!(dummy_cities.last) }
|
221
234
|
before { expect(Chewy.client).to receive(:bulk).once.and_call_original }
|
222
235
|
specify { expect(import(dummy_cities, update_fields: [:name])).to eq(true) }
|
223
236
|
end
|
@@ -226,10 +239,8 @@ describe Chewy::Type::Import do
|
|
226
239
|
context 'fields integrational' do
|
227
240
|
before do
|
228
241
|
stub_index(:cities) do
|
229
|
-
|
230
|
-
|
231
|
-
field :object, type: 'object'
|
232
|
-
end
|
242
|
+
field :name
|
243
|
+
field :object, type: 'object'
|
233
244
|
end
|
234
245
|
end
|
235
246
|
|
@@ -257,9 +268,14 @@ describe Chewy::Type::Import do
|
|
257
268
|
import(objects, update_fields: %i[name])
|
258
269
|
|
259
270
|
expect(payload).to eq(
|
260
|
-
errors: {
|
271
|
+
errors: {
|
272
|
+
index: {{
|
273
|
+
'type' => 'mapper_parsing_exception',
|
274
|
+
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
275
|
+
} => %w[2 4]}
|
276
|
+
},
|
261
277
|
import: {index: 6},
|
262
|
-
|
278
|
+
index: CitiesIndex
|
263
279
|
)
|
264
280
|
expect(imported_cities).to match_array([
|
265
281
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 11}},
|
@@ -275,9 +291,14 @@ describe Chewy::Type::Import do
|
|
275
291
|
import(objects, batch_size: 2, update_fields: %i[name])
|
276
292
|
|
277
293
|
expect(payload).to eq(
|
278
|
-
errors: {
|
294
|
+
errors: {
|
295
|
+
index: {{
|
296
|
+
'type' => 'mapper_parsing_exception',
|
297
|
+
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
298
|
+
} => %w[2 4]}
|
299
|
+
},
|
279
300
|
import: {index: 6},
|
280
|
-
|
301
|
+
index: CitiesIndex
|
281
302
|
)
|
282
303
|
expect(imported_cities).to match_array([
|
283
304
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 11}},
|
@@ -287,7 +308,7 @@ describe Chewy::Type::Import do
|
|
287
308
|
end
|
288
309
|
|
289
310
|
context do
|
290
|
-
before { CitiesIndex
|
311
|
+
before { CitiesIndex.import!(objects[4]) }
|
291
312
|
|
292
313
|
specify do
|
293
314
|
payload = subscribe_notification
|
@@ -296,9 +317,14 @@ describe Chewy::Type::Import do
|
|
296
317
|
import(objects, batch_size: 2, update_fields: %i[name])
|
297
318
|
|
298
319
|
expect(payload).to eq(
|
299
|
-
errors: {
|
320
|
+
errors: {
|
321
|
+
index: {{
|
322
|
+
'type' => 'mapper_parsing_exception',
|
323
|
+
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
324
|
+
} => %w[2 4]}
|
325
|
+
},
|
300
326
|
import: {index: 6},
|
301
|
-
|
327
|
+
index: CitiesIndex
|
302
328
|
)
|
303
329
|
expect(imported_cities).to match_array([
|
304
330
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 11}},
|
@@ -309,7 +335,7 @@ describe Chewy::Type::Import do
|
|
309
335
|
end
|
310
336
|
|
311
337
|
context do
|
312
|
-
before { CitiesIndex
|
338
|
+
before { CitiesIndex.import!(old_objects[1], old_objects[3], objects[4]) }
|
313
339
|
|
314
340
|
specify do
|
315
341
|
payload = subscribe_notification
|
@@ -319,7 +345,7 @@ describe Chewy::Type::Import do
|
|
319
345
|
|
320
346
|
expect(payload).to eq(
|
321
347
|
import: {index: 6},
|
322
|
-
|
348
|
+
index: CitiesIndex
|
323
349
|
)
|
324
350
|
expect(imported_cities).to match_array([
|
325
351
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 11}},
|
@@ -338,7 +364,7 @@ describe Chewy::Type::Import do
|
|
338
364
|
|
339
365
|
expect(payload).to eq(
|
340
366
|
import: {index: 6},
|
341
|
-
|
367
|
+
index: CitiesIndex
|
342
368
|
)
|
343
369
|
expect(imported_cities).to match_array([
|
344
370
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 11}},
|
@@ -357,8 +383,8 @@ describe Chewy::Type::Import do
|
|
357
383
|
|
358
384
|
# Full match doesn't work here.
|
359
385
|
expect(payload[:errors][:update].keys).to match([
|
360
|
-
hash_including('type' => 'document_missing_exception', 'reason' => '[
|
361
|
-
hash_including('type' => 'document_missing_exception', 'reason' => '[
|
386
|
+
hash_including('type' => 'document_missing_exception', 'reason' => '[_doc][1]: document missing'),
|
387
|
+
hash_including('type' => 'document_missing_exception', 'reason' => '[_doc][3]: document missing')
|
362
388
|
])
|
363
389
|
expect(payload[:errors][:update].values).to eq([['1'], ['3']])
|
364
390
|
expect(imported_cities).to match_array([
|
@@ -370,7 +396,7 @@ describe Chewy::Type::Import do
|
|
370
396
|
end
|
371
397
|
|
372
398
|
context do
|
373
|
-
before { CitiesIndex
|
399
|
+
before { CitiesIndex.import!(old_objects) }
|
374
400
|
|
375
401
|
specify do
|
376
402
|
payload = subscribe_notification
|
@@ -380,7 +406,7 @@ describe Chewy::Type::Import do
|
|
380
406
|
|
381
407
|
expect(payload).to eq(
|
382
408
|
import: {index: 6},
|
383
|
-
|
409
|
+
index: CitiesIndex
|
384
410
|
)
|
385
411
|
expect(imported_cities).to match_array([
|
386
412
|
{'id' => '1', 'name' => 'Name11', 'object' => {'foo' => 1}},
|
@@ -394,7 +420,7 @@ describe Chewy::Type::Import do
|
|
394
420
|
end
|
395
421
|
|
396
422
|
context do
|
397
|
-
before { CitiesIndex
|
423
|
+
before { CitiesIndex.import!(old_objects) }
|
398
424
|
|
399
425
|
specify do
|
400
426
|
payload = subscribe_notification
|
@@ -403,9 +429,14 @@ describe Chewy::Type::Import do
|
|
403
429
|
import(objects, update_fields: %i[object])
|
404
430
|
|
405
431
|
expect(payload).to eq(
|
406
|
-
errors: {
|
432
|
+
errors: {
|
433
|
+
update: {{
|
434
|
+
'type' => 'mapper_parsing_exception',
|
435
|
+
'reason' => 'object mapping for [object] tried to parse field [object] as object, but found a concrete value'
|
436
|
+
} => %w[2 4]}
|
437
|
+
},
|
407
438
|
import: {index: 6},
|
408
|
-
|
439
|
+
index: CitiesIndex
|
409
440
|
)
|
410
441
|
expect(imported_cities).to match_array([
|
411
442
|
{'id' => '1', 'name' => 'Name1', 'object' => {'foo' => 11}},
|
@@ -423,9 +454,8 @@ describe Chewy::Type::Import do
|
|
423
454
|
context do
|
424
455
|
before do
|
425
456
|
stub_index(:cities) do
|
426
|
-
|
427
|
-
|
428
|
-
end
|
457
|
+
index_scope City
|
458
|
+
field :name, type: 'object'
|
429
459
|
end
|
430
460
|
end
|
431
461
|
|
@@ -437,9 +467,8 @@ describe Chewy::Type::Import do
|
|
437
467
|
context do
|
438
468
|
before do
|
439
469
|
stub_index(:cities) do
|
440
|
-
|
441
|
-
|
442
|
-
end
|
470
|
+
index_scope City
|
471
|
+
field :name, type: 'object', value: -> { name == 'name1' ? name : {name: name} }
|
443
472
|
end
|
444
473
|
end
|
445
474
|
|
@@ -451,19 +480,19 @@ describe Chewy::Type::Import do
|
|
451
480
|
|
452
481
|
context 'default_import_options are set' do
|
453
482
|
before do
|
454
|
-
CitiesIndex
|
483
|
+
CitiesIndex.default_import_options(batch_size: 500)
|
455
484
|
end
|
456
485
|
|
457
486
|
specify do
|
458
|
-
expect(CitiesIndex
|
459
|
-
CitiesIndex
|
487
|
+
expect(CitiesIndex.adapter).to receive(:import).with(any_args, hash_including(batch_size: 500))
|
488
|
+
CitiesIndex.import
|
460
489
|
end
|
461
490
|
end
|
462
491
|
end
|
463
492
|
|
464
493
|
describe '.import', :orm do
|
465
494
|
def import(*args)
|
466
|
-
CitiesIndex
|
495
|
+
CitiesIndex.import(*args)
|
467
496
|
end
|
468
497
|
|
469
498
|
it_behaves_like 'importing'
|
@@ -472,62 +501,99 @@ describe Chewy::Type::Import do
|
|
472
501
|
def import(*args)
|
473
502
|
options = args.extract_options!
|
474
503
|
options[:parallel] = 0
|
475
|
-
CitiesIndex
|
504
|
+
CitiesIndex.import(*args, options)
|
476
505
|
end
|
477
506
|
|
478
507
|
it_behaves_like 'importing'
|
479
508
|
end
|
509
|
+
|
510
|
+
context 'with parent-child relationship' do
|
511
|
+
before do
|
512
|
+
stub_model(:comment)
|
513
|
+
stub_index(:comments) do
|
514
|
+
index_scope Comment
|
515
|
+
field :content
|
516
|
+
field :comment_type, type: :join, relations: {question: %i[answer comment], answer: :vote}, join: {type: :comment_type, id: :commented_id}
|
517
|
+
end
|
518
|
+
end
|
519
|
+
|
520
|
+
let!(:comments) do
|
521
|
+
[
|
522
|
+
Comment.create!(id: 1, content: 'Where is Nemo?', comment_type: :question),
|
523
|
+
Comment.create!(id: 2, content: 'Here.', comment_type: :answer, commented_id: 1),
|
524
|
+
Comment.create!(id: 3, content: 'There!', comment_type: :answer, commented_id: 1),
|
525
|
+
Comment.create!(id: 4, content: 'Yes, he is here.', comment_type: :vote, commented_id: 2)
|
526
|
+
]
|
527
|
+
end
|
528
|
+
|
529
|
+
def imported_comments
|
530
|
+
CommentsIndex.all.map do |comment|
|
531
|
+
comment.attributes.except('_score', '_explanation')
|
532
|
+
end
|
533
|
+
end
|
534
|
+
|
535
|
+
it 'imports parent and children' do
|
536
|
+
CommentsIndex.import!(comments.map(&:id))
|
537
|
+
|
538
|
+
expect(imported_comments).to match_array([
|
539
|
+
{'id' => '1', 'content' => 'Where is Nemo?', 'comment_type' => 'question'},
|
540
|
+
{'id' => '2', 'content' => 'Here.', 'comment_type' => {'name' => 'answer', 'parent' => 1}},
|
541
|
+
{'id' => '3', 'content' => 'There!', 'comment_type' => {'name' => 'answer', 'parent' => 1}},
|
542
|
+
{'id' => '4', 'content' => 'Yes, he is here.', 'comment_type' => {'name' => 'vote', 'parent' => 2}}
|
543
|
+
])
|
544
|
+
|
545
|
+
answer_ids = CommentsIndex.query(has_parent: {parent_type: 'question', query: {match: {content: 'Where'}}}).pluck(:_id)
|
546
|
+
expect(answer_ids).to match_array(%w[2 3])
|
547
|
+
end
|
548
|
+
end
|
480
549
|
end
|
481
550
|
|
482
551
|
describe '.import!', :orm do
|
483
|
-
specify { expect { CitiesIndex
|
552
|
+
specify { expect { CitiesIndex.import! }.not_to raise_error }
|
484
553
|
|
485
554
|
context do
|
486
555
|
before do
|
487
556
|
stub_index(:cities) do
|
488
|
-
|
489
|
-
|
490
|
-
end
|
557
|
+
index_scope City
|
558
|
+
field :name, type: 'object'
|
491
559
|
end
|
492
560
|
end
|
493
561
|
|
494
|
-
specify { expect { CitiesIndex
|
562
|
+
specify { expect { CitiesIndex.import!(dummy_cities) }.to raise_error Chewy::ImportFailed }
|
495
563
|
end
|
496
564
|
end
|
497
565
|
|
498
566
|
describe '.compose' do
|
499
567
|
before do
|
500
568
|
stub_index(:cities) do
|
501
|
-
|
502
|
-
|
503
|
-
collection.map { |o| [o.name, o.name + '42'] }.to_h
|
504
|
-
end
|
505
|
-
field :name, value: ->(o, c) { c.names[o.name] }
|
506
|
-
field :rating
|
569
|
+
crutch :names do |collection|
|
570
|
+
collection.to_h { |o| [o.name, "#{o.name}42"] }
|
507
571
|
end
|
572
|
+
field :name, value: ->(o, c) { c.names[o.name] }
|
573
|
+
field :rating
|
508
574
|
end
|
509
575
|
end
|
510
576
|
|
511
577
|
specify do
|
512
|
-
expect(CitiesIndex
|
578
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42)))
|
513
579
|
.to eq('name' => 'Name42', 'rating' => 42)
|
514
580
|
end
|
515
581
|
|
516
582
|
specify do
|
517
|
-
expect(CitiesIndex
|
583
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42), fields: %i[name]))
|
518
584
|
.to eq('name' => 'Name42')
|
519
585
|
end
|
520
586
|
|
521
587
|
context 'witchcraft' do
|
522
|
-
before { CitiesIndex
|
588
|
+
before { CitiesIndex.witchcraft! }
|
523
589
|
|
524
590
|
specify do
|
525
|
-
expect(CitiesIndex
|
591
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42)))
|
526
592
|
.to eq('name' => 'Name42', 'rating' => 42)
|
527
593
|
end
|
528
594
|
|
529
595
|
specify do
|
530
|
-
expect(CitiesIndex
|
596
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42), fields: %i[name]))
|
531
597
|
.to eq('name' => 'Name42')
|
532
598
|
end
|
533
599
|
end
|
@@ -536,12 +602,12 @@ describe Chewy::Type::Import do
|
|
536
602
|
let(:crutches) { double(names: {'Name' => 'Name43'}) }
|
537
603
|
|
538
604
|
specify do
|
539
|
-
expect(CitiesIndex
|
605
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42), crutches))
|
540
606
|
.to eq('name' => 'Name43', 'rating' => 42)
|
541
607
|
end
|
542
608
|
|
543
609
|
specify do
|
544
|
-
expect(CitiesIndex
|
610
|
+
expect(CitiesIndex.compose(double(name: 'Name', rating: 42), crutches, fields: %i[name]))
|
545
611
|
.to eq('name' => 'Name43')
|
546
612
|
end
|
547
613
|
end
|