elastomer-client 3.2.2 → 6.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (114) hide show
  1. checksums.yaml +4 -4
  2. data/.devcontainer/devcontainer.json +46 -0
  3. data/.devcontainer/postCreateCommand.sh +4 -0
  4. data/.github/dependabot.yaml +11 -0
  5. data/.github/workflows/main.yml +45 -0
  6. data/.github/workflows/rubocop.yml +15 -0
  7. data/.gitignore +1 -1
  8. data/.rubocop.yml +13 -65
  9. data/.ruby-version +1 -0
  10. data/CHANGELOG.md +76 -0
  11. data/Gemfile +18 -1
  12. data/README.md +110 -51
  13. data/Rakefile +3 -1
  14. data/docker/compose.yaml +71 -0
  15. data/docker/elasticsearch8plus.yml +13 -0
  16. data/docs/README.md +4 -5
  17. data/docs/bulk_indexing.md +1 -1
  18. data/docs/client.md +20 -33
  19. data/docs/cluster.md +8 -8
  20. data/docs/docs.md +5 -5
  21. data/docs/index.md +4 -4
  22. data/docs/multi_search.md +1 -1
  23. data/docs/notifications.md +3 -3
  24. data/docs/scan_scroll.md +1 -1
  25. data/docs/snapshots.md +1 -1
  26. data/docs/templates.md +1 -1
  27. data/elastomer-client.gemspec +7 -16
  28. data/lib/{elastomer → elastomer_client}/client/bulk.rb +70 -47
  29. data/lib/{elastomer → elastomer_client}/client/cluster.rb +18 -16
  30. data/lib/{elastomer → elastomer_client}/client/delete_by_query.rb +6 -4
  31. data/lib/{elastomer → elastomer_client}/client/docs.rb +82 -72
  32. data/lib/{elastomer → elastomer_client}/client/errors.rb +7 -17
  33. data/lib/{elastomer → elastomer_client}/client/index.rb +55 -79
  34. data/lib/{elastomer → elastomer_client}/client/multi_percolate.rb +7 -5
  35. data/lib/{elastomer → elastomer_client}/client/multi_search.rb +5 -3
  36. data/lib/{elastomer → elastomer_client}/client/native_delete_by_query.rb +6 -6
  37. data/lib/{elastomer → elastomer_client}/client/nodes.rb +11 -10
  38. data/lib/{elastomer → elastomer_client}/client/percolator.rb +9 -10
  39. data/lib/elastomer_client/client/reindex.rb +29 -0
  40. data/lib/{elastomer → elastomer_client}/client/repository.rb +7 -5
  41. data/lib/{elastomer → elastomer_client}/client/rest_api_spec/api_spec.rb +7 -6
  42. data/lib/{elastomer → elastomer_client}/client/rest_api_spec/api_spec_v5_6.rb +1 -1
  43. data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_13.rb +7567 -0
  44. data/lib/elastomer_client/client/rest_api_spec/api_spec_v8_7.rb +6553 -0
  45. data/lib/{elastomer → elastomer_client}/client/rest_api_spec/rest_api.rb +6 -4
  46. data/lib/{elastomer → elastomer_client}/client/rest_api_spec.rb +3 -2
  47. data/lib/{elastomer → elastomer_client}/client/scroller.rb +17 -16
  48. data/lib/{elastomer → elastomer_client}/client/snapshot.rb +10 -8
  49. data/lib/{elastomer → elastomer_client}/client/tasks.rb +9 -13
  50. data/lib/{elastomer → elastomer_client}/client/template.rb +10 -9
  51. data/lib/elastomer_client/client/update_by_query.rb +50 -0
  52. data/lib/{elastomer → elastomer_client}/client.rb +51 -62
  53. data/lib/{elastomer → elastomer_client}/core_ext/time.rb +2 -0
  54. data/lib/{elastomer → elastomer_client}/middleware/compress.rb +2 -2
  55. data/lib/{elastomer → elastomer_client}/middleware/encode_json.rb +4 -2
  56. data/lib/{elastomer → elastomer_client}/middleware/limit_size.rb +5 -3
  57. data/lib/{elastomer → elastomer_client}/middleware/opaque_id.rb +10 -7
  58. data/lib/{elastomer → elastomer_client}/middleware/parse_json.rb +5 -3
  59. data/lib/{elastomer → elastomer_client}/notifications.rb +17 -15
  60. data/lib/elastomer_client/version.rb +9 -0
  61. data/lib/elastomer_client/version_support.rb +24 -0
  62. data/script/bootstrap +4 -2
  63. data/script/console +3 -1
  64. data/script/generate-rest-api-spec +77 -22
  65. data/test/assertions.rb +32 -39
  66. data/test/client/bulk_test.rb +165 -143
  67. data/test/client/cluster_test.rb +35 -13
  68. data/test/client/docs_test.rb +387 -274
  69. data/test/client/errors_test.rb +38 -40
  70. data/test/client/index_test.rb +243 -202
  71. data/test/client/multi_percolate_test.rb +46 -41
  72. data/test/client/multi_search_test.rb +122 -67
  73. data/test/client/native_delete_by_query_test.rb +96 -88
  74. data/test/client/nodes_test.rb +21 -10
  75. data/test/client/percolator_test.rb +19 -14
  76. data/test/client/reindex_test.rb +76 -0
  77. data/test/client/repository_test.rb +31 -19
  78. data/test/client/rest_api_spec/api_spec_test.rb +13 -11
  79. data/test/client/rest_api_spec/rest_api_test.rb +9 -7
  80. data/test/client/scroller_test.rb +44 -70
  81. data/test/client/snapshot_test.rb +38 -21
  82. data/test/client/stubbed_client_test.rb +7 -4
  83. data/test/client/tasks_test.rb +12 -17
  84. data/test/client/template_test.rb +34 -13
  85. data/test/client/update_by_query_test.rb +137 -0
  86. data/test/client_test.rb +158 -92
  87. data/test/core_ext/time_test.rb +14 -12
  88. data/test/middleware/encode_json_test.rb +18 -7
  89. data/test/middleware/opaque_id_test.rb +18 -14
  90. data/test/middleware/parse_json_test.rb +17 -9
  91. data/test/mock_response.rb +30 -0
  92. data/test/notifications_test.rb +15 -8
  93. data/test/test_helper.rb +40 -97
  94. data/test/version_support_test.rb +13 -78
  95. metadata +60 -208
  96. data/.overcommit.yml +0 -5
  97. data/.travis.yml +0 -34
  98. data/docker/docker-compose.cibuild.yml +0 -8
  99. data/docker/docker-compose.es24.yml +0 -34
  100. data/docker/docker-compose.es56.yml +0 -37
  101. data/docs/warmers.md +0 -3
  102. data/lib/elastomer/client/app_delete_by_query.rb +0 -144
  103. data/lib/elastomer/client/rest_api_spec/api_spec_v2_3.rb +0 -2232
  104. data/lib/elastomer/client/rest_api_spec/api_spec_v2_4.rb +0 -2250
  105. data/lib/elastomer/client/warmer.rb +0 -98
  106. data/lib/elastomer/version.rb +0 -7
  107. data/lib/elastomer/version_support.rb +0 -182
  108. data/script/cibuild +0 -103
  109. data/script/cibuild-elastomer-client +0 -1
  110. data/script/cibuild-elastomer-client-es24 +0 -8
  111. data/script/cibuild-elastomer-client-es56 +0 -8
  112. data/test/client/app_delete_by_query_test.rb +0 -192
  113. data/test/client/es_5_x_warmer_test.rb +0 -13
  114. data/test/client/warmer_test.rb +0 -60
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require_relative "../test_helper"
2
4
 
3
- describe Elastomer::Client::Index do
5
+ describe ElastomerClient::Client::Index do
4
6
 
5
7
  before do
6
8
  @name = "elastomer-index-test"
@@ -14,25 +16,27 @@ describe Elastomer::Client::Index do
14
16
 
15
17
  it "does not require an index name" do
16
18
  index = $client.index
19
+
17
20
  assert_nil index.name
18
21
  end
19
22
 
20
23
  it "determines if an index exists" do
21
- assert !@index.exists?, "the index should not yet exist"
24
+ refute_predicate @index, :exists?, "the index should not yet exist"
22
25
  end
23
26
 
24
27
  it "determines if an index exists with .exist?" do
25
- assert !@index.exist?, "the index should not yet exist"
28
+ refute_predicate @index, :exist?, "the index should not yet exist"
26
29
  end
27
30
 
28
31
  describe "when creating an index" do
29
32
  it "creates an index" do
30
33
  @index.create({})
31
- assert @index.exists?, "the index should now exist"
34
+
35
+ assert_predicate @index, :exists?, "the index should now exist"
32
36
  end
33
37
 
34
38
  it "creates an index with settings" do
35
- @index.create :settings => { :number_of_shards => 3, :number_of_replicas => 0 }
39
+ @index.create settings: { number_of_shards: 3, number_of_replicas: 0 }
36
40
  settings = @index.get_settings[@name]["settings"]
37
41
 
38
42
  assert_equal "3", settings["index"]["number_of_shards"]
@@ -40,7 +44,7 @@ describe Elastomer::Client::Index do
40
44
  end
41
45
 
42
46
  it "creates an index with settings with .settings" do
43
- @index.create :settings => { :number_of_shards => 3, :number_of_replicas => 0 }
47
+ @index.create settings: { number_of_shards: 3, number_of_replicas: 0 }
44
48
  settings = @index.settings[@name]["settings"]
45
49
 
46
50
  assert_equal "3", settings["index"]["number_of_shards"]
@@ -49,175 +53,180 @@ describe Elastomer::Client::Index do
49
53
 
50
54
  it "adds mappings for document types" do
51
55
  @index.create(
52
- :settings => { :number_of_shards => 1, :number_of_replicas => 0 },
53
- :mappings => {
54
- :doco => {
55
- :_source => { :enabled => false },
56
- :_all => { :enabled => false },
57
- :properties => {
58
- :title => $client.version_support.text(analyzer: "standard"),
59
- :author => $client.version_support.keyword
60
- }
56
+ settings: { number_of_shards: 1, number_of_replicas: 0 },
57
+ mappings: mappings_wrapper("book", {
58
+ _source: { enabled: false },
59
+ properties: {
60
+ title: { type: "text", analyzer: "standard" },
61
+ author: { type: "keyword" }
61
62
  }
62
- }
63
+ }, true)
63
64
  )
64
65
 
65
- assert @index.exists?, "the index should now exist"
66
- assert_mapping_exists @index.get_mapping[@name], "doco"
66
+ assert_predicate @index, :exists?, "the index should now exist"
67
+ assert_mapping_exists @index.get_mapping[@name], "book"
67
68
  end
68
69
 
69
70
  it "adds mappings for document types with .mapping" do
70
71
  @index.create(
71
- :settings => { :number_of_shards => 1, :number_of_replicas => 0 },
72
- :mappings => {
73
- :doco => {
74
- :_source => { :enabled => false },
75
- :_all => { :enabled => false },
76
- :properties => {
77
- :title => $client.version_support.text(analyzer: "standard"),
78
- :author => $client.version_support.keyword
79
- }
72
+ settings: { number_of_shards: 1, number_of_replicas: 0 },
73
+ mappings: mappings_wrapper("book", {
74
+ _source: { enabled: false },
75
+ properties: {
76
+ title: { type: "text", analyzer: "standard" },
77
+ author: { type: "keyword" }
80
78
  }
81
- }
79
+ }, true)
82
80
  )
83
81
 
84
- assert @index.exists?, "the index should now exist"
85
- assert_mapping_exists @index.mapping[@name], "doco"
82
+ assert_predicate @index, :exists?, "the index should now exist"
83
+ assert_mapping_exists @index.mapping[@name], "book"
86
84
  end
87
85
  end
88
86
 
89
87
  it "updates index settings" do
90
- @index.create :settings => { :number_of_shards => 1, :number_of_replicas => 0 }
88
+ @index.create settings: { number_of_shards: 1, number_of_replicas: 0 }
91
89
 
92
90
  @index.update_settings "index.number_of_replicas" => 1
93
91
  settings = @index.settings[@name]["settings"]
94
92
 
95
- # COMPATIBILITY
96
- # ES 1.0 changed the default return format of index settings to always
97
- # expand nested properties, e.g.
98
- # {"index.number_of_replicas": "1"} changed to
99
- # {"index": {"number_of_replicas":"1"}}
100
-
101
- # To support both versions, we check for either return format.
102
- value = settings["index.number_of_replicas"] ||
103
- settings["index"]["number_of_replicas"]
104
- assert_equal "1", value
93
+ assert_equal "1", settings["index"]["number_of_replicas"]
105
94
  end
106
95
 
107
96
  it "updates document mappings" do
108
97
  @index.create(
109
- :mappings => {
110
- :doco => {
111
- :_source => { :enabled => false },
112
- :_all => { :enabled => false },
113
- :properties => {:title => $client.version_support.text(analyzer: "standard")}
114
- }
115
- }
98
+ mappings: mappings_wrapper("book", {
99
+ _source: { enabled: false },
100
+ properties: { title: { type: "text", analyzer: "standard" } }
101
+ }, true)
116
102
  )
117
103
 
118
- assert_property_exists @index.mapping[@name], "doco", "title"
104
+ assert_property_exists @index.mapping[@name], "book", "title"
119
105
 
120
- @index.update_mapping "doco", { :doco => { :properties => {
121
- :author => $client.version_support.keyword
122
- }}}
106
+ if $client.version_support.es_version_8_plus?
107
+ @index.update_mapping "_doc", { properties: {
108
+ author: { type: "keyword" }
109
+ }}
110
+ else
111
+ @index.update_mapping "book", { book: { properties: {
112
+ author: { type: "keyword" }
113
+ }}}
114
+ end
123
115
 
124
- assert_property_exists @index.mapping[@name], "doco", "author"
125
- assert_property_exists @index.mapping[@name], "doco", "title"
116
+ assert_property_exists @index.mapping[@name], "book", "author"
117
+ assert_property_exists @index.mapping[@name], "book", "title"
126
118
 
127
- @index.update_mapping "mux_mool", { :mux_mool => { :properties => {
128
- :song => $client.version_support.keyword
129
- }}}
119
+ # ES8 removes mapping types so test adding a new mapping type only for versions < 8
120
+ if !$client.version_support.es_version_8_plus?
121
+ @index.update_mapping "mux_mool", { mux_mool: { properties: {
122
+ song: { type: "keyword" }
123
+ }}}
130
124
 
131
- assert_property_exists @index.mapping[@name], "mux_mool", "song"
125
+ assert_property_exists @index.mapping[@name], "mux_mool", "song"
126
+ end
132
127
  end
133
128
 
134
129
  it "updates document mappings with .put_mapping" do
135
130
  @index.create(
136
- :mappings => {
137
- :doco => {
138
- :_source => { :enabled => false },
139
- :_all => { :enabled => false },
140
- :properties => {:title => $client.version_support.text(analyzer: "standard")}
141
- }
142
- }
131
+ mappings: mappings_wrapper("book", {
132
+ _source: { enabled: false },
133
+ properties: { title: { type: "text", analyzer: "standard" } }
134
+ }, true)
143
135
  )
144
136
 
145
- assert_property_exists @index.mapping[@name], "doco", "title"
137
+ assert_property_exists @index.mapping[@name], "book", "title"
146
138
 
147
- @index.put_mapping "doco", { :doco => { :properties => {
148
- :author => $client.version_support.keyword
149
- }}}
139
+ if $client.version_support.es_version_8_plus?
140
+ @index.put_mapping "_doc", { properties: {
141
+ author: { type: "keyword" }
142
+ }}
143
+ else
144
+ @index.put_mapping "book", { book: { properties: {
145
+ author: { type: "keyword" }
146
+ }}}
147
+ end
150
148
 
151
- assert_property_exists @index.mapping[@name], "doco", "author"
152
- assert_property_exists @index.mapping[@name], "doco", "title"
149
+ assert_property_exists @index.mapping[@name], "book", "author"
150
+ assert_property_exists @index.mapping[@name], "book", "title"
153
151
 
154
- @index.put_mapping "mux_mool", { :mux_mool => { :properties => {
155
- :song => $client.version_support.keyword
156
- }}}
152
+ # ES8 removes mapping types so test adding a new mapping type only for versions < 8
153
+ if !$client.version_support.es_version_8_plus?
154
+ @index.put_mapping "mux_mool", { mux_mool: { properties: {
155
+ song: { type: "keyword" }
156
+ }}}
157
157
 
158
- assert_property_exists @index.mapping[@name], "mux_mool", "song"
158
+ assert_property_exists @index.mapping[@name], "mux_mool", "song"
159
+ end
159
160
  end
160
161
 
161
162
  it "lists all aliases to the index" do
162
163
  @index.create(nil)
164
+
163
165
  assert_equal({@name => {"aliases" => {}}}, @index.get_aliases)
164
166
 
165
- $client.cluster.update_aliases :add => {:index => @name, :alias => "foofaloo"}
166
- $client.cluster.update_aliases :add => {:index => @name, :alias => "bar"}
167
+ $client.cluster.update_aliases add: {index: @name, alias: "foofaloo"}
168
+ $client.cluster.update_aliases add: {index: @name, alias: "bar"}
167
169
 
168
170
  assert_equal({@name => {"aliases" => {"foofaloo" => {}, "bar" => {}}}}, @index.get_aliases)
169
171
 
170
172
  assert_equal({@name => {"aliases" => {"foofaloo" => {}}}}, @index.get_alias("f*"))
171
173
  assert_equal({@name => {"aliases" => {"foofaloo" => {}, "bar" => {}}}}, @index.get_alias("*"))
172
174
 
173
- if fetching_non_existent_alias_returns_error?
174
- exception = assert_raises(Elastomer::Client::RequestError) do
175
- @index.get_alias("not-there")
176
- end
177
- assert_equal("alias [not-there] missing", exception.message)
178
- assert_equal(404, exception.status)
175
+ exception = assert_raises(ElastomerClient::Client::RequestError) do
176
+ @index.get_alias("not-there")
177
+ end
179
178
 
180
- exception = assert_raises(Elastomer::Client::RequestError) do
179
+ assert_equal("alias [not-there] missing", exception.message)
180
+ assert_equal(404, exception.status)
181
+
182
+ # In ES8, when you use wildcards, an error is not raised if no match is found
183
+ if $client.version_support.es_version_8_plus?
184
+ assert_empty(@index.get_alias("not*"))
185
+ else
186
+ exception = assert_raises(ElastomerClient::Client::RequestError) do
181
187
  @index.get_alias("not*")
182
188
  end
189
+
183
190
  assert_equal("alias [not*] missing", exception.message)
184
191
  assert_equal(404, exception.status)
185
- else
186
- assert_equal({}, @index.get_alias("not-there"))
187
- assert_equal({}, @index.get_alias("not*"))
188
192
  end
189
193
  end
190
194
 
191
195
  it "adds and deletes aliases to the index" do
192
196
  @index.create(nil)
197
+
193
198
  assert_empty @index.get_alias("*")
194
199
 
195
200
  @index.add_alias "gondolin"
196
201
  aliases = @index.get_alias("*")
202
+
197
203
  assert_equal %w[gondolin], aliases[@name]["aliases"].keys.sort
198
204
 
199
205
  @index.add_alias "gondor"
200
206
  aliases = @index.get_alias("*")
207
+
201
208
  assert_equal %w[gondolin gondor], aliases[@name]["aliases"].keys.sort
202
209
 
203
210
  @index.delete_alias "gon*"
211
+
204
212
  assert_empty @index.get_alias("*")
205
213
  end
206
214
 
207
215
  it "analyzes text and returns tokens" do
208
216
  tokens = @index.analyze({text: "Just a few words to analyze.", analyzer: "standard"}, index: nil)
209
217
  tokens = tokens["tokens"].map { |h| h["token"] }
218
+
210
219
  assert_equal %w[just a few words to analyze], tokens
211
220
 
212
221
  @index.create(
213
- :settings => {
214
- :number_of_shards => 1,
215
- :number_of_replicas => 0,
216
- :analysis => {
217
- :analyzer => {
218
- :english_standard => {
219
- :type => :standard,
220
- :stopwords => "_english_"
222
+ settings: {
223
+ number_of_shards: 1,
224
+ number_of_replicas: 0,
225
+ analysis: {
226
+ analyzer: {
227
+ english_standard: {
228
+ type: :standard,
229
+ stopwords: "_english_"
221
230
  }
222
231
  }
223
232
  }
@@ -227,41 +236,57 @@ describe Elastomer::Client::Index do
227
236
 
228
237
  tokens = @index.analyze({text: "Just a few words to analyze.", analyzer: "english_standard"})
229
238
  tokens = tokens["tokens"].map { |h| h["token"] }
239
+
230
240
  assert_equal %w[just few words analyze], tokens
231
241
  end
232
242
 
243
+ it "accepts a type param and does not throw an error for ES8" do
244
+ if !$client.version_support.es_version_8_plus?
245
+ skip "This test is only needed for ES8 onwards"
246
+ end
247
+
248
+ @index.create(
249
+ mappings: mappings_wrapper("book", {
250
+ _source: { enabled: false },
251
+ properties: { title: { type: "text", analyzer: "standard" } }
252
+ }, true)
253
+ )
254
+
255
+ assert_property_exists @index.mapping(type: "book")[@name], "book", "title"
256
+
257
+ @index.update_mapping "book", { properties: {
258
+ author: { type: "keyword" }
259
+ }}
260
+
261
+ assert_property_exists @index.mapping(type: "book")[@name], "book", "author"
262
+ assert_property_exists @index.mapping(type: "book")[@name], "book", "title"
263
+ end
264
+
233
265
  describe "when an index does not exist" do
234
266
  it "raises an IndexNotFoundError on delete" do
235
267
  index = $client.index("index-that-does-not-exist")
236
- assert_raises(Elastomer::Client::IndexNotFoundError) { index.delete }
268
+ assert_raises(ElastomerClient::Client::IndexNotFoundError) { index.delete }
237
269
  end
238
270
  end
239
271
 
240
272
  describe "when an index exists" do
241
273
  before do
242
274
  suggest = {
243
- :type => "completion",
244
- :analyzer => "simple",
245
- :search_analyzer => "simple",
275
+ type: "completion",
276
+ analyzer: "simple",
277
+ search_analyzer: "simple",
246
278
  }
247
279
 
248
- # COMPATIBILITY
249
- # ES 5.x drops support for index-time payloads
250
- suggest[:payloads] = false if index_time_payloads?
251
-
252
280
  @index.create(
253
- :settings => { :number_of_shards => 1, :number_of_replicas => 0 },
254
- :mappings => {
255
- :doco => {
256
- :_source => { :enabled => false },
257
- :_all => { :enabled => false },
258
- :properties => {
259
- :title => $client.version_support.text(analyzer: "standard"),
260
- :author => $client.version_support.keyword,
261
- :suggest => suggest
262
- }
281
+ settings: { number_of_shards: 1, number_of_replicas: 0 },
282
+ mappings: mappings_wrapper("book", {
283
+ _source: { enabled: true },
284
+ properties: {
285
+ title: { type: "text", analyzer: "standard" },
286
+ author: { type: "keyword" },
287
+ suggest:
263
288
  }
264
- }
289
+ }, true)
265
290
  )
266
291
  wait_for_index(@name)
267
292
  end
@@ -269,31 +294,37 @@ describe Elastomer::Client::Index do
269
294
  #TODO assert this only hits the desired index
270
295
  it "deletes" do
271
296
  response = @index.delete
297
+
272
298
  assert_acknowledged response
273
299
  end
274
300
 
275
301
  it "opens" do
276
302
  response = @index.open
303
+
277
304
  assert_acknowledged response
278
305
  end
279
306
 
280
307
  it "closes" do
281
308
  response = @index.close
309
+
282
310
  assert_acknowledged response
283
311
  end
284
312
 
285
313
  it "refreshes" do
286
314
  response = @index.refresh
315
+
287
316
  assert_equal 0, response["_shards"]["failed"]
288
317
  end
289
318
 
290
319
  it "flushes" do
291
320
  response = @index.flush
321
+
292
322
  assert_equal 0, response["_shards"]["failed"]
293
323
  end
294
324
 
295
325
  it "force merges" do
296
326
  response = @index.forcemerge
327
+
297
328
  assert_equal 0, response["_shards"]["failed"]
298
329
  end
299
330
 
@@ -303,11 +334,13 @@ describe Elastomer::Client::Index do
303
334
 
304
335
  it "recovery" do
305
336
  response = @index.recovery
337
+
306
338
  assert_includes response, "elastomer-index-test"
307
339
  end
308
340
 
309
341
  it "clears caches" do
310
342
  response = @index.clear_cache
343
+
311
344
  assert_equal 0, response["_shards"]["failed"]
312
345
  end
313
346
 
@@ -321,130 +354,138 @@ describe Elastomer::Client::Index do
321
354
  end
322
355
 
323
356
  it "gets segments" do
324
- @index.docs("foo").index("foo" => "bar")
325
357
  response = @index.segments
358
+
326
359
  assert_includes response["indices"], "elastomer-index-test"
327
360
  end
328
361
 
329
362
  it "deletes by query" do
330
- @index.docs("foo").index("foo" => "bar")
363
+ @index.docs.index(document_wrapper("book", { _id: 1, title: "Book 1" }))
331
364
  @index.refresh
332
- r = @index.delete_by_query(:q => "*")
365
+ r = @index.delete_by_query(q: "*")
333
366
 
334
- if supports_native_delete_by_query?
335
- assert_equal(1, r['deleted'])
336
- else
337
- assert_equal({
338
- "_all" => {
339
- "found" => 1,
340
- "deleted" => 1,
341
- "missing" => 0,
342
- "failed" => 0,
343
- },
344
- @name => {
345
- "found" => 1,
346
- "deleted" => 1,
347
- "missing" => 0,
348
- "failed" => 0,
349
- }
350
- }, r["_indices"])
351
- end
367
+ assert_equal(1, r["deleted"])
368
+ end
369
+
370
+ it "updates by query" do
371
+ @index.docs.index(document_wrapper("book", { _id: 1, title: "Book 1" }))
372
+ @index.refresh
373
+ r = @index.update_by_query(
374
+ query: { match_all: {}},
375
+ script: { source: "ctx._source.title = 'Book 2'" }
376
+ )
377
+
378
+ @index.refresh
379
+ updated = @index.docs.get(id: 1, type: "book")
380
+
381
+ assert_equal(1, r["updated"])
382
+ assert_equal("Book 2", updated["_source"]["title"])
383
+
384
+ r = @index.update_by_query({
385
+ query: { match_all: {}},
386
+ script: { source: "ctx._source.title = 'Book 3'" }
387
+ }, conflicts: "proceed")
388
+
389
+ @index.refresh
390
+ updated = @index.docs.get(id: 1, type: "book")
391
+
392
+ assert_equal(1, r["updated"])
393
+ assert_equal("Book 3", updated["_source"]["title"])
352
394
  end
353
395
 
354
396
  it "creates a Percolator" do
355
397
  id = "1"
356
398
  percolator = @index.percolator id
399
+
357
400
  assert_equal id, percolator.id
358
401
  end
359
402
 
360
403
  it "performs multi percolate queries" do
361
- # COMPATIBILITY
362
- if requires_percolator_mapping?
363
- @index.update_mapping("percolator", { :properties => { :query => { :type => "percolator" } } })
364
- end
365
-
366
- @index.docs.index \
367
- :_id => 1,
368
- :_type => "doco",
369
- :title => "the author of logging",
370
- :author => "pea53"
404
+ # The _percolate endpoint is removed from ES8, and replaced with percolate queries via _search and _msearch
405
+ if !$client.version_support.es_version_8_plus?
406
+ @index.update_mapping("percolator", { properties: { query: { type: "percolator" } } })
407
+
408
+ @index.docs.index \
409
+ document_wrapper("book", {
410
+ _id: 1,
411
+ title: "Book 1 by author 1",
412
+ author: "Author 1"
413
+ })
414
+
415
+ @index.docs.index \
416
+ document_wrapper("book", {
417
+ _id: 2,
418
+ title: "Book 2 by author 2",
419
+ author: "Author 2"
420
+ })
421
+
422
+ @index.percolator("1").create query: { match_all: { } }
423
+ @index.percolator("2").create query: { match: { author: "Author 1" } }
424
+ @index.refresh
371
425
 
372
- @index.docs.index \
373
- :_id => 2,
374
- :_type => "doco",
375
- :title => "the author of rubber-band",
376
- :author => "grantr"
426
+ h = @index.multi_percolate(type: "book") do |m|
427
+ m.percolate author: "Author 1"
428
+ m.percolate author: "Author 2"
429
+ m.count({ author: "Author 2" }, {})
430
+ end
377
431
 
378
- @index.percolator("1").create :query => { :match_all => { } }
379
- @index.percolator("2").create :query => { :match => { :author => "pea53" } }
380
- @index.refresh
432
+ response1, response2, response3 = h["responses"]
381
433
 
382
- h = @index.multi_percolate(:type => "doco") do |m|
383
- m.percolate :author => "pea53"
384
- m.percolate :author => "grantr"
385
- m.count({ :author => "grantr" }, {})
434
+ assert_equal ["1", "2"], response1["matches"].map { |match| match["_id"] }.sort
435
+ assert_equal ["1"], response2["matches"].map { |match| match["_id"] }.sort
436
+ assert_equal 1, response3["total"]
386
437
  end
387
-
388
- response1, response2, response3 = h["responses"]
389
- assert_equal ["1", "2"], response1["matches"].map { |match| match["_id"] }.sort
390
- assert_equal ["1"], response2["matches"].map { |match| match["_id"] }.sort
391
- assert_equal 1, response3["total"]
392
438
  end
393
439
 
394
440
  it "performs suggestion queries" do
395
- @index.docs.index \
396
- :_id => 1,
397
- :_type => "doco",
398
- :title => "the magnificent",
399
- :author => "greg",
400
- :suggest => {:input => "greg", :weight => 2}
401
-
402
- @index.docs.index \
403
- :_id => 2,
404
- :_type => "doco",
405
- :title => "the author of rubber-band",
406
- :author => "grant",
407
- :suggest => {:input => "grant", :weight => 1}
441
+ # The _suggest endpoint is removed from ES8, suggest functionality is now via _search
442
+ if !$client.version_support.es_version_8_plus?
443
+ @index.docs.index \
444
+ document_wrapper("book", {
445
+ _id: 1,
446
+ title: "the magnificent",
447
+ author: "greg",
448
+ suggest: {input: "greg", weight: 2}
449
+ })
450
+
451
+ @index.docs.index \
452
+ document_wrapper("book", {
453
+ _id: 2,
454
+ title: "the author of rubber-band",
455
+ author: "grant",
456
+ suggest: {input: "grant", weight: 1}
457
+ })
458
+ @index.refresh
459
+ response = @index.suggest({name: {text: "gr", completion: {field: :suggest}}})
408
460
 
409
- @index.refresh
410
- response = @index.suggest({:name => {:text => "gr", :completion => {:field => :suggest}}})
461
+ assert response.key?("name")
462
+ hash = response["name"].first
463
+
464
+ assert_equal "gr", hash["text"]
411
465
 
412
- assert response.key?("name")
413
- hash = response["name"].first
414
- assert_equal "gr", hash["text"]
466
+ options = hash["options"]
415
467
 
416
- options = hash["options"]
417
- assert_equal 2, options.length
418
- assert_equal "greg", options.first["text"]
419
- assert_equal "grant", options.last["text"]
468
+ assert_equal 2, options.length
469
+ assert_equal "greg", options.first["text"]
470
+ assert_equal "grant", options.last["text"]
471
+ end
420
472
  end
421
473
 
422
474
  it "handles output parameter of field" do
423
- document = {
475
+ document = document_wrapper("book", {
424
476
  _id: 1,
425
- _type: "doco",
426
477
  title: "the magnificent",
427
478
  author: "greg",
428
479
  suggest: {input: %w[Greg greg], output: "Greg", weight: 2}
429
- }
480
+ })
430
481
 
431
- if supports_suggest_output?
432
- # It is not an error to index `output`...
482
+ # Indexing the document fails when `output` is provided
483
+ exception = assert_raises(ElastomerClient::Client::RequestError) do
433
484
  @index.docs.index(document)
434
-
435
- # ...and `output` is used in the search response
436
- @index.refresh
437
- response = @index.suggest({:name => {:text => "gr", :completion => {:field => :suggest}}})
438
- assert_equal "Greg", response.fetch("name").first.fetch("options").first.fetch("text")
439
- else
440
- # Indexing the document fails when `output` is provided
441
- exception = assert_raises(Elastomer::Client::RequestError) do
442
- @index.docs.index(document)
443
- end
444
-
445
- assert_equal(400, exception.status)
446
- assert_match(/\[output\]/, exception.message)
447
485
  end
486
+
487
+ assert_equal(400, exception.status)
488
+ assert_match(/\[output\]/, exception.message)
448
489
  end
449
490
  end
450
491
  end