elastomer-client 3.2.3 → 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 +73 -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 +5 -3
  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 +166 -141
  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 "forwardable"
2
4
 
3
- module Elastomer::Client::RestApiSpec
5
+ module ElastomerClient::Client::RestApiSpec
4
6
  class RestApi
5
7
  extend Forwardable
6
8
 
@@ -40,7 +42,7 @@ module Elastomer::Client::RestApiSpec
40
42
  end
41
43
 
42
44
  def select_parts(from:)
43
- from.select {|k,v| valid_part?(k)}
45
+ from.select { |k, v| valid_part?(k) }
44
46
  end
45
47
 
46
48
  def valid_part?(part)
@@ -48,7 +50,7 @@ module Elastomer::Client::RestApiSpec
48
50
  end
49
51
 
50
52
  def select_params(from:)
51
- from.select {|k,v| valid_param?(k)}
53
+ from.select { |k, v| valid_param?(k) }
52
54
  end
53
55
 
54
56
  def valid_param?(param)
@@ -1,5 +1,6 @@
1
+ # frozen_string_literal: true
1
2
 
2
- module Elastomer
3
+ module ElastomerClient
3
4
  class Client
4
5
 
5
6
  # Provides access to the versioned REST API specs for Elasticsearch.
@@ -34,7 +35,7 @@ module Elastomer
34
35
  # Internal: Convert a dotted version String into an underscore format
35
36
  # suitable for use in Ruby class names.
36
37
  def self.to_class_version(version)
37
- version.to_s.split(".").slice(0,2).join("_")
38
+ version.to_s.split(".").slice(0, 2).join("_")
38
39
  end
39
40
  end
40
41
  end
@@ -1,4 +1,6 @@
1
- module Elastomer
1
+ # frozen_string_literal: true
2
+
3
+ module ElastomerClient
2
4
  class Client
3
5
 
4
6
  # Create a new Scroller instance for scrolling all results from a `query`.
@@ -19,7 +21,7 @@ module Elastomer
19
21
  # end
20
22
  #
21
23
  # Returns a new Scroller instance
22
- def scroll( query, opts = {} )
24
+ def scroll(query, opts = {})
23
25
  Scroller.new(self, query, opts)
24
26
  end
25
27
 
@@ -42,7 +44,7 @@ module Elastomer
42
44
  # end
43
45
  #
44
46
  # Returns a new Scroller instance
45
- def scan( query, opts = {} )
47
+ def scan(query, opts = {})
46
48
  Scroller.new(self, add_sort_by_doc(query), opts)
47
49
  end
48
50
 
@@ -55,7 +57,6 @@ module Elastomer
55
57
  # :type - the document type to search
56
58
  # :scroll - the keep alive time of the scrolling request (5 minutes by default)
57
59
  # :size - the number of documents per shard to fetch per scroll
58
- # :search_type - set to 'scan' for scan semantics # DEPRECATED in ES 2.1.0 - use a Scroll query sorted by _doc: https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-request-search-type.html#scan
59
60
  #
60
61
  # Examples
61
62
  #
@@ -70,8 +71,9 @@ module Elastomer
70
71
  # # repeat until there are no more hits
71
72
  #
72
73
  # Returns the response body as a Hash.
73
- def start_scroll( opts = {} )
74
+ def start_scroll(opts = {})
74
75
  opts = opts.merge action: "search.start_scroll", rest_api: "search"
76
+ opts.delete(:type) if version_support.es_version_8_plus?
75
77
  response = get "{/index}{/type}/_search", opts
76
78
  response.body
77
79
  end
@@ -95,8 +97,8 @@ module Elastomer
95
97
  # # repeat until the results are empty
96
98
  #
97
99
  # Returns the response body as a Hash.
98
- def continue_scroll( scroll_id, scroll = "5m" )
99
- response = get "/_search/scroll", body: {scroll_id: scroll_id}, scroll: scroll, action: "search.scroll", rest_api: "scroll"
100
+ def continue_scroll(scroll_id, scroll = "5m")
101
+ response = get "/_search/scroll", body: {scroll_id:}, scroll:, action: "search.scroll", rest_api: "scroll"
100
102
  response.body
101
103
  rescue RequestError => err
102
104
  if err.error && err.error["caused_by"]["type"] == "search_context_missing_exception"
@@ -112,7 +114,7 @@ module Elastomer
112
114
  # scroll_id - One or more scroll IDs
113
115
  #
114
116
  # Returns the response body as a Hash.
115
- def clear_scroll( scroll_ids )
117
+ def clear_scroll(scroll_ids)
116
118
  response = delete "/_search/scroll", body: {scroll_id: Array(scroll_ids)}, action: "search.clear_scroll", rest_api: "clear_scroll"
117
119
  response.body
118
120
  end
@@ -129,7 +131,7 @@ module Elastomer
129
131
  end
130
132
 
131
133
  if query.has_key? :sort
132
- raise ArgumentError, "Query cannot contain a sort (found sort '#{query[:sort]}' in query: #{query})"
134
+ raise ArgumentError, "Query cannot contain a sort (found sort '#{query[:sort]}' in query: #{query})"
133
135
  end
134
136
 
135
137
  query.merge(sort: [:_doc])
@@ -150,14 +152,13 @@ module Elastomer
150
152
  # See https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-scroll.html
151
153
  # and https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-search-type.html#scan
152
154
  #
153
- # client - Elastomer::Client used for HTTP requests to the server
155
+ # client - ElastomerClient::Client used for HTTP requests to the server
154
156
  # query - The query to scroll as a Hash or a JSON encoded String
155
157
  # opts - Options Hash
156
158
  # :index - the name of the index to search
157
159
  # :type - the document type to search
158
160
  # :scroll - the keep alive time of the scrolling request (5 minutes by default)
159
161
  # :size - the number of documents per shard to fetch per scroll
160
- # :search_type - set to 'scan' for scan semantics # DEPRECATED in ES 2.1.0 - use a Scroll query sorted by _doc: https://www.elastic.co/guide/en/elasticsearch/reference/2.3/search-request-search-type.html#scan
161
162
  #
162
163
  # Examples
163
164
  #
@@ -167,7 +168,7 @@ module Elastomer
167
168
  # doc['_source']
168
169
  # }
169
170
  #
170
- def initialize( client, query, opts = {} )
171
+ def initialize(client, query, opts = {})
171
172
  @client = client
172
173
 
173
174
  @opts = DEFAULT_OPTS.merge({ body: query }).merge(opts)
@@ -230,7 +231,7 @@ module Elastomer
230
231
  # end
231
232
  #
232
233
  # Returns this Scroller instance.
233
- def each_document( &block )
234
+ def each_document(&block)
234
235
  each { |hits| hits["hits"].each(&block) }
235
236
  end
236
237
 
@@ -238,12 +239,12 @@ module Elastomer
238
239
  # cluster and no further documents can be returned by this Scroller
239
240
  # instance.
240
241
  #
241
- # Returns nil if the `scroll_id` is not valid; returns the reponse body if
242
+ # Returns nil if the `scroll_id` is not valid; returns the response body if
242
243
  # the `scroll_id` was cleared.
243
244
  def clear!
244
245
  return if scroll_id.nil?
245
246
  client.clear_scroll(scroll_id)
246
- rescue ::Elastomer::Client::IllegalArgument
247
+ rescue ::ElastomerClient::Client::IllegalArgument
247
248
  nil
248
249
  end
249
250
 
@@ -269,4 +270,4 @@ module Elastomer
269
270
 
270
271
  end # Scroller
271
272
  end # Client
272
- end # Elastomer
273
+ end # ElastomerClient
@@ -1,4 +1,6 @@
1
- module Elastomer
1
+ # frozen_string_literal: true
2
+
3
+ module ElastomerClient
2
4
  class Client
3
5
 
4
6
  # Provides access to snapshot API commands.
@@ -15,7 +17,7 @@ module Elastomer
15
17
  # Create a new snapshot object for making API requests that pertain to
16
18
  # creating, restoring, deleting, and retrieving snapshots.
17
19
  #
18
- # client - Elastomer::Client used for HTTP requests to the server
20
+ # client - ElastomerClient::Client used for HTTP requests to the server
19
21
  # repository - The name of the repository as a String. Cannot be nil if
20
22
  # snapshot name is not nil.
21
23
  # name - The name of the snapshot as a String
@@ -37,7 +39,7 @@ module Elastomer
37
39
  def exists?(params = {})
38
40
  response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, action: "snapshot.exists", rest_api: "snapshot.get")
39
41
  response.success?
40
- rescue Elastomer::Client::Error => err
42
+ rescue ElastomerClient::Client::Error => err
41
43
  if err.error && err.error.dig("root_cause", 0, "type") == "snapshot_missing_exception"
42
44
  false
43
45
  else
@@ -54,7 +56,7 @@ module Elastomer
54
56
  #
55
57
  # Returns the response body as a Hash
56
58
  def create(body = {}, params = {})
57
- response = client.put "/_snapshot/{repository}/{snapshot}", update_params(params, body: body, action: "snapshot.create", rest_api: "snapshot.create")
59
+ response = client.put "/_snapshot/{repository}/{snapshot}", update_params(params, body:, action: "snapshot.create", rest_api: "snapshot.create")
58
60
  response.body
59
61
  end
60
62
 
@@ -67,7 +69,7 @@ module Elastomer
67
69
  def get(params = {})
68
70
  # Set snapshot name or we'll get the repository instead
69
71
  snapshot = name || "_all"
70
- response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, snapshot: snapshot, action: "snapshot.get", rest_api: "snapshot.get")
72
+ response = client.get "/_snapshot/{repository}/{snapshot}", update_params(params, snapshot:, action: "snapshot.get", rest_api: "snapshot.get")
71
73
  response.body
72
74
  end
73
75
 
@@ -90,7 +92,7 @@ module Elastomer
90
92
  #
91
93
  # Returns the response body as a Hash
92
94
  def restore(body = {}, params = {})
93
- response = client.post "/_snapshot/{repository}/{snapshot}/_restore", update_params(params, body: body, action: "snapshot.restore", rest_api: "snapshot.restore")
95
+ response = client.post "/_snapshot/{repository}/{snapshot}/_restore", update_params(params, body:, action: "snapshot.restore", rest_api: "snapshot.restore")
94
96
  response.body
95
97
  end
96
98
 
@@ -112,7 +114,7 @@ module Elastomer
112
114
  # overrides - Optional parameter overrides as a Hash
113
115
  #
114
116
  # Returns a new params Hash.
115
- def update_params( params, overrides = nil )
117
+ def update_params(params, overrides = nil)
116
118
  h = defaults.update params
117
119
  h.update overrides unless overrides.nil?
118
120
  h
@@ -120,7 +122,7 @@ module Elastomer
120
122
 
121
123
  # Internal: Returns a Hash containing default parameters.
122
124
  def defaults
123
- { repository: repository, snapshot: name }
125
+ { repository:, snapshot: name }
124
126
  end
125
127
  end
126
128
  end
@@ -1,4 +1,6 @@
1
- module Elastomer
1
+ # frozen_string_literal: true
2
+
3
+ module ElastomerClient
2
4
  class Client
3
5
 
4
6
  # Returns a Tasks instance for querying the cluster bound to this client for
@@ -15,7 +17,7 @@ module Elastomer
15
17
  # Create a new Tasks for introspecting on internal cluster activity.
16
18
  # More context: https://www.elastic.co/guide/en/elasticsearch/reference/5.6/tasks.html
17
19
  #
18
- # client - Elastomer::Client used for HTTP requests to the server
20
+ # client - ElastomerClient::Client used for HTTP requests to the server
19
21
  #
20
22
  # Raises IncompatibleVersionException if caller attempts to access Tasks API on ES version < 5.0.0
21
23
  def initialize(client)
@@ -63,10 +65,8 @@ module Elastomer
63
65
  raise ArgumentError, "invalid node ID provided: #{node_id.inspect}" if node_id.to_s.empty?
64
66
  raise ArgumentError, "invalid task ID provided: #{task_id.inspect}" unless task_id.is_a?(Integer)
65
67
 
66
- rest_api = client.version_support.supports_tasks_get? ? "tasks.get" : "tasks.list"
67
-
68
68
  # in this API, the task ID is included in the path, not as a request parameter.
69
- response = client.get "/_tasks/{task_id}", params.merge(task_id: "#{node_id}:#{task_id}", action: "tasks.get", rest_api: rest_api)
69
+ response = client.get "/_tasks/{task_id}", params.merge(task_id: "#{node_id}:#{task_id}", action: "tasks.get", rest_api: "tasks.get")
70
70
  response.body
71
71
  end
72
72
 
@@ -92,11 +92,7 @@ module Elastomer
92
92
  parent_task_id = "#{parent_node_id}:#{parent_task_id}"
93
93
  params = params.merge(action: "tasks.parent", rest_api: "tasks.list")
94
94
 
95
- if client.version_support.supports_parent_task_id?
96
- params[:parent_task_id] = parent_task_id
97
- else
98
- params[:parent_task] = parent_task_id
99
- end
95
+ params[:parent_task_id] = parent_task_id
100
96
 
101
97
  response = client.get "/_tasks", params
102
98
  response.body
@@ -115,8 +111,8 @@ module Elastomer
115
111
  #
116
112
  # Returns the response body as a Hash when timeout expires or target tasks complete
117
113
  # COMPATIBILITY WARNING: the response body differs between ES versions for this API
118
- def wait_for(timeout = "10s", params = {})
119
- self.get params.merge(wait_for_completion: true, timeout: timeout)
114
+ def wait_for(timeout = "10s", params = {})
115
+ self.get params.merge(wait_for_completion: true, timeout:)
120
116
  end
121
117
 
122
118
  # Wait for the specified amount of time (10 seconds by default) for some task(s) to complete.
@@ -137,7 +133,7 @@ module Elastomer
137
133
  raise ArgumentError, "invalid node ID provided: #{node_id.inspect}" if node_id.to_s.empty?
138
134
  raise ArgumentError, "invalid task ID provided: #{task_id.inspect}" unless task_id.is_a?(Integer)
139
135
 
140
- self.get_by_id(node_id, task_id, params.merge(wait_for_completion: true, timeout: timeout))
136
+ self.get_by_id(node_id, task_id, params.merge(wait_for_completion: true, timeout:))
141
137
  end
142
138
 
143
139
  # Cancels a task running on a particular node.
@@ -1,9 +1,10 @@
1
+ # frozen_string_literal: true
1
2
 
2
- module Elastomer
3
+ module ElastomerClient
3
4
  class Client
4
5
 
5
6
  # Returns a Template instance.
6
- def template( name )
7
+ def template(name)
7
8
  Template.new self, name
8
9
  end
9
10
 
@@ -13,10 +14,10 @@ module Elastomer
13
14
  # Create a new template client for making API requests that pertain to
14
15
  # template management.
15
16
  #
16
- # client - Elastomer::Client used for HTTP requests to the server
17
+ # client - ElastomerClient::Client used for HTTP requests to the server
17
18
  # name - The name of the template as a String
18
19
  #
19
- def initialize( client, name )
20
+ def initialize(client, name)
20
21
  @client = client
21
22
  @name = name
22
23
  end
@@ -24,7 +25,7 @@ module Elastomer
24
25
  attr_reader :client, :name
25
26
 
26
27
  # Returns true if the template already exists on the cluster.
27
- def exists?( params = {} )
28
+ def exists?(params = {})
28
29
  response = client.head "/_template/{template}", update_params(params, action: "template.exists", rest_api: "indices.exists_template")
29
30
  response.success?
30
31
  end
@@ -36,7 +37,7 @@ module Elastomer
36
37
  # params - Parameters Hash
37
38
  #
38
39
  # Returns the response body as a Hash
39
- def get( params = {} )
40
+ def get(params = {})
40
41
  response = client.get "/_template/{template}", update_params(params, action: "template.get", rest_api: "indices.get_template")
41
42
  response.body
42
43
  end
@@ -48,7 +49,7 @@ module Elastomer
48
49
  # params - Parameters Hash
49
50
  #
50
51
  # Returns the response body as a Hash
51
- def create( template, params = {} )
52
+ def create(template, params = {})
52
53
  response = client.put "/_template/{template}", update_params(params, body: template, action: "template.create", rest_api: "indices.put_template")
53
54
  response.body
54
55
  end
@@ -59,7 +60,7 @@ module Elastomer
59
60
  # params - Parameters Hash
60
61
  #
61
62
  # Returns the response body as a Hash
62
- def delete( params = {} )
63
+ def delete(params = {})
63
64
  response = client.delete "/_template/{template}", update_params(params, action: "template.delete", rest_api: "indices.delete_template")
64
65
  response.body
65
66
  end
@@ -71,7 +72,7 @@ module Elastomer
71
72
  # overrides - Optional parameter overrides as a Hash
72
73
  #
73
74
  # Returns a new params Hash.
74
- def update_params( params, overrides = nil )
75
+ def update_params(params, overrides = nil)
75
76
  h = defaults.update params
76
77
  h.update overrides unless overrides.nil?
77
78
  h
@@ -0,0 +1,50 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ElastomerClient
4
+ class Client
5
+ # Update documents based on a query using the Elasticsearch _update_by_query API.
6
+ #
7
+ # query - The query body as a Hash
8
+ # params - Parameters Hash
9
+ #
10
+ # Examples
11
+ #
12
+ # # request body query
13
+ # update_by_query({
14
+ # "script": {
15
+ # "source": "ctx._source.count++",
16
+ # "lang": "painless"
17
+ # },
18
+ # "query": {
19
+ # "term": {
20
+ # "user.id": "kimchy"
21
+ # }
22
+ # }
23
+ # })
24
+ #
25
+ # See https://www.elastic.co/guide/en/elasticsearch/reference/8.7/docs-update-by-query.html
26
+ #
27
+ # Returns a Hash containing the _update_by_query response body.
28
+ def update_by_query(query, parameters = {})
29
+ UpdateByQuery.new(self, query, parameters).execute
30
+ end
31
+
32
+ class UpdateByQuery
33
+ attr_reader :client, :query, :parameters
34
+
35
+ def initialize(client, query, parameters)
36
+ @client = client
37
+ @query = query
38
+ @parameters = parameters
39
+ end
40
+
41
+ def execute
42
+ # TODO: Require index parameter. type is optional.
43
+ updated_params = parameters.merge(body: query, action: "update_by_query", rest_api: "update_by_query")
44
+ updated_params.delete(:type) if client.version_support.es_version_8_plus?
45
+ response = client.post("/{index}{/type}/_update_by_query", updated_params)
46
+ response.body
47
+ end
48
+ end
49
+ end
50
+ end