search_flip 3.6.0 → 3.7.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: a241c0ab86244a53caab6b7d8dbcd8f441d9e7fc40837cc9afa7f57e6c7e5da0
4
- data.tar.gz: f42562bd8af88780accd33c91c112c9f81b42de8945aa956c118b7faff75c6f6
3
+ metadata.gz: fa5f6a747338bfb614f3500dbd0fb38413014ac6d97ef481090b0b37b1f249e4
4
+ data.tar.gz: e2aa8a79527447a52a9f5900cf8f66483d1f103b3834b82f1aae6b7503dfb0f7
5
5
  SHA512:
6
- metadata.gz: ad60516d947d060ca1fe049a80059c18e9deb76f7c380b0279cd11cd5b5e0fb811d3a46a12220fd731b793ce1a6728f23e6cb242410f584d040e874a2bed7d78
7
- data.tar.gz: 415962179b2e3ead79296851746b5f4892bdfbce64d09ae6ef2a2f0df83fa265b1c00a8a549d42013911eaff7ecc0b0460d20ef5c72d096f070d1adce4d0797c
6
+ metadata.gz: 9ba068c05072934816850cc5a63641097fb358004e5adac1edf86eb524ed60f8a8e03eab3d8725fc274459bdf73d4f892a449d934e873be0591a01849a3de43b
7
+ data.tar.gz: 81e2a611a50df1f72ae09fc5c28f43130f2cbce2a7c40102d8322fce851d78ec4e710ddd5905f8907cba52bcb100ac9137d31d89016bdf1cae6c2d08b91e4f5f
data/CHANGELOG.md CHANGED
@@ -1,6 +1,15 @@
1
1
 
2
2
  # CHANGELOG
3
3
 
4
+ ## v3.7.1
5
+
6
+ * Fix thread-safety issue of http-rb
7
+
8
+ ## v3.7.0
9
+
10
+ * Add `SearchFlip::Connection#bulk` to allow more clean bulk indexing to
11
+ multiple indices at once
12
+
4
13
  ## v3.6.0
5
14
 
6
15
  * Support Elasticsearch v8
data/README.md CHANGED
@@ -9,7 +9,7 @@
9
9
  Using SearchFlip it is dead-simple to create index classes that correspond to
10
10
  [Elasticsearch](https://www.elastic.co/) indices and to manipulate, query and
11
11
  aggregate these indices using a chainable, concise, yet powerful DSL. Finally,
12
- SearchFlip supports Elasticsearch 2.x, 5.x, 6.x, 7.x. Check section
12
+ SearchFlip supports Elasticsearch 2.x, 5.x, 6.x, 7.x and 8.x. Check section
13
13
  [Feature Support](#feature-support) for version dependent features.
14
14
 
15
15
  ```ruby
@@ -355,6 +355,51 @@ module SearchFlip
355
355
  raise e
356
356
  end
357
357
 
358
+ # Initiates and yields a bulk object, such that index, import, create,
359
+ # update and delete requests can be appended to the bulk request. Please
360
+ # note that you need to manually pass the desired index name as well as
361
+ # type name (depending on the Elasticsearch version) when using #bulk on a
362
+ # connection object or Elasticsearch will return an error. After the bulk
363
+ # requests are successfully processed all existing indices will
364
+ # subsequently be refreshed when auto_refresh is enabled.
365
+ #
366
+ # @see SearchFlip::Config See SearchFlip::Config for auto_refresh
367
+ #
368
+ # @example
369
+ # connection = SearchFlip::Connection.new
370
+ #
371
+ # connection.bulk ignore_errors: [409] do |bulk|
372
+ # bulk.create comment.id, CommentIndex.serialize(comment),
373
+ # _index: CommentIndex.index_name, version: comment.version, version_type: "external_gte"
374
+ #
375
+ # bulk.delete product.id, _index: ProductIndex.index_name, routing: product.user_id
376
+ #
377
+ # # ...
378
+ # end
379
+ #
380
+ # @param options [Hash] Specifies options regarding the bulk indexing
381
+ # @option options ignore_errors [Array] Specifies an array of http status
382
+ # codes that shouldn't raise any exceptions, like eg 409 for conflicts,
383
+ # ie when optimistic concurrency control is used.
384
+ # @option options raise [Boolean] Prevents any exceptions from being
385
+ # raised. Please note that this only applies to the bulk response, not to
386
+ # the request in general, such that connection errors, etc will still
387
+ # raise.
388
+
389
+ def bulk(options = {})
390
+ default_options = {
391
+ http_client: http_client,
392
+ bulk_limit: bulk_limit,
393
+ bulk_max_mb: bulk_max_mb
394
+ }
395
+
396
+ SearchFlip::Bulk.new("#{base_url}/_bulk", default_options.merge(options)) do |indexer|
397
+ yield indexer
398
+ end
399
+
400
+ refresh if SearchFlip::Config[:auto_refresh]
401
+ end
402
+
358
403
  # Returns the full Elasticsearch type URL, ie base URL, index name with
359
404
  # prefix and type name.
360
405
  #
@@ -59,6 +59,7 @@ module SearchFlip
59
59
 
60
60
  def execute(method, uri, options = {})
61
61
  final_request = plugins.inject(self) { |res, cur| cur.call(res, method, uri, options) }
62
+ final_request = final_request.headers({}) # Prevent thread-safety issue of http-rb: https://github.com/httprb/http/issues/558
62
63
  response = final_request.request.send(method, uri, options)
63
64
 
64
65
  raise SearchFlip::ResponseError.new(code: response.code, body: response.body.to_s) unless response.status.success?
@@ -601,7 +601,7 @@ module SearchFlip
601
601
  scope
602
602
  end
603
603
 
604
- # Initiates and yields the bulk object, such that index, import, create,
604
+ # Initiates and yields a bulk object, such that index, import, create,
605
605
  # update and delete requests can be appended to the bulk request. Sends a
606
606
  # refresh request afterwards if auto_refresh is enabled.
607
607
  #
@@ -1,3 +1,3 @@
1
1
  module SearchFlip
2
- VERSION = "3.6.0"
2
+ VERSION = "3.7.1"
3
3
  end
data/search_flip.gemspec CHANGED
@@ -15,7 +15,6 @@ Gem::Specification.new do |spec|
15
15
 
16
16
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
- spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
20
  spec.post_install_message = <<~MESSAGE
@@ -315,6 +315,96 @@ RSpec.describe SearchFlip::Connection do
315
315
  end
316
316
  end
317
317
 
318
+ describe "#bulk" do
319
+ it "imports objects to the specified indices" do
320
+ connection = SearchFlip::Connection.new
321
+
322
+ bulk = proc do
323
+ connection.bulk do |indexer|
324
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
325
+ indexer.index 2, { id: 2 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
326
+ indexer.index 1, { id: 1 }, _index: CommentIndex.index_name, ** connection.version.to_i < 8 ? { _type: CommentIndex.type_name } : {}
327
+ end
328
+ end
329
+
330
+ expect(&bulk).to(change { CommentIndex.total_count }.by(1).and(change { CommentIndex.total_count }.by(1)))
331
+ end
332
+
333
+ it "raises when no index is given" do
334
+ connection = SearchFlip::Connection.new
335
+
336
+ bulk = proc do
337
+ connection.bulk do |indexer|
338
+ indexer.index 1, id: 1
339
+ end
340
+ end
341
+
342
+ expect(&bulk).to raise_error(SearchFlip::ResponseError)
343
+ end
344
+
345
+ it "respects options" do
346
+ connection = SearchFlip::Connection.new
347
+
348
+ connection.bulk do |indexer|
349
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
350
+ indexer.index 2, { id: 2 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
351
+ end
352
+
353
+ bulk = proc do
354
+ connection.bulk do |indexer|
355
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, version: 1, version_type: "external", ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
356
+ indexer.index 2, { id: 2 }, _index: ProductIndex.index_name, version: 1, version_type: "external", ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
357
+ end
358
+ end
359
+
360
+ expect(&bulk).to raise_error(SearchFlip::Bulk::Error)
361
+
362
+ bulk = proc do
363
+ connection.bulk ignore_errors: [409] do |indexer|
364
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, version: 1, version_type: "external", ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
365
+ indexer.index 2, { id: 2 }, _index: ProductIndex.index_name, version: 1, version_type: "external", ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
366
+ end
367
+ end
368
+
369
+ expect(&bulk).not_to(change { ProductIndex.total_count })
370
+ end
371
+
372
+ it "passes default options" do
373
+ allow(SearchFlip::Bulk).to receive(:new)
374
+
375
+ connection = SearchFlip::Connection.new
376
+
377
+ connection.bulk do |indexer|
378
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
379
+ end
380
+
381
+ expect(SearchFlip::Bulk).to have_received(:new).with(
382
+ anything,
383
+ http_client: connection.http_client,
384
+ bulk_limit: connection.bulk_limit,
385
+ bulk_max_mb: connection.bulk_max_mb
386
+ )
387
+ end
388
+
389
+ it "passes custom options" do
390
+ allow(SearchFlip::Bulk).to receive(:new)
391
+
392
+ connection = SearchFlip::Connection.new
393
+
394
+ options = {
395
+ bulk_limit: "bulk limit",
396
+ bulk_max_mb: "bulk max mb",
397
+ http_client: "http client"
398
+ }
399
+
400
+ connection.bulk(options) do |indexer|
401
+ indexer.index 1, { id: 1 }, _index: ProductIndex.index_name, ** connection.version.to_i < 8 ? { _type: ProductIndex.type_name } : {}
402
+ end
403
+
404
+ expect(SearchFlip::Bulk).to have_received(:new).with(anything, options)
405
+ end
406
+ end
407
+
318
408
  describe "#index_url" do
319
409
  it "returns the index url for the specified index" do
320
410
  connection = SearchFlip::Connection.new(base_url: "base_url")
data/spec/spec_helper.rb CHANGED
@@ -16,6 +16,8 @@ RSpec.configure do |config|
16
16
  TestIndex.delete_index if TestIndex.index_exists?
17
17
  ProductIndex.match_all.delete
18
18
  Product.delete_all
19
+ CommentIndex.match_all.delete
20
+ Comment.delete_all
19
21
  end
20
22
  end
21
23
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: search_flip
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.6.0
4
+ version: 3.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Vetter
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-03-27 00:00:00.000000000 Z
11
+ date: 2022-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -305,18 +305,4 @@ rubygems_version: 3.2.3
305
305
  signing_key:
306
306
  specification_version: 4
307
307
  summary: Full-Featured Elasticsearch Ruby Client with a Chainable DSL
308
- test_files:
309
- - spec/delegate_matcher.rb
310
- - spec/search_flip/aggregation_spec.rb
311
- - spec/search_flip/aws_sigv4_plugin_spec.rb
312
- - spec/search_flip/bulk_spec.rb
313
- - spec/search_flip/connection_spec.rb
314
- - spec/search_flip/criteria_spec.rb
315
- - spec/search_flip/http_client_spec.rb
316
- - spec/search_flip/index_spec.rb
317
- - spec/search_flip/json_spec.rb
318
- - spec/search_flip/model_spec.rb
319
- - spec/search_flip/null_instrumenter_spec.rb
320
- - spec/search_flip/response_spec.rb
321
- - spec/search_flip/result_spec.rb
322
- - spec/spec_helper.rb
308
+ test_files: []