elastomer-client 0.3.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.
Files changed (49) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.ruby-version +1 -0
  4. data/CHANGELOG.md +4 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +108 -0
  8. data/Rakefile +9 -0
  9. data/docs/notifications.md +71 -0
  10. data/elastomer-client.gemspec +30 -0
  11. data/lib/elastomer/client.rb +307 -0
  12. data/lib/elastomer/client/bulk.rb +257 -0
  13. data/lib/elastomer/client/cluster.rb +208 -0
  14. data/lib/elastomer/client/docs.rb +432 -0
  15. data/lib/elastomer/client/errors.rb +51 -0
  16. data/lib/elastomer/client/index.rb +407 -0
  17. data/lib/elastomer/client/multi_search.rb +115 -0
  18. data/lib/elastomer/client/nodes.rb +87 -0
  19. data/lib/elastomer/client/scan.rb +161 -0
  20. data/lib/elastomer/client/template.rb +85 -0
  21. data/lib/elastomer/client/warmer.rb +96 -0
  22. data/lib/elastomer/core_ext/time.rb +7 -0
  23. data/lib/elastomer/middleware/encode_json.rb +51 -0
  24. data/lib/elastomer/middleware/opaque_id.rb +69 -0
  25. data/lib/elastomer/middleware/parse_json.rb +39 -0
  26. data/lib/elastomer/notifications.rb +83 -0
  27. data/lib/elastomer/version.rb +7 -0
  28. data/script/bootstrap +16 -0
  29. data/script/cibuild +28 -0
  30. data/script/console +9 -0
  31. data/script/testsuite +10 -0
  32. data/test/assertions.rb +74 -0
  33. data/test/client/bulk_test.rb +226 -0
  34. data/test/client/cluster_test.rb +113 -0
  35. data/test/client/docs_test.rb +394 -0
  36. data/test/client/index_test.rb +244 -0
  37. data/test/client/multi_search_test.rb +129 -0
  38. data/test/client/nodes_test.rb +35 -0
  39. data/test/client/scan_test.rb +84 -0
  40. data/test/client/stubbed_client_tests.rb +40 -0
  41. data/test/client/template_test.rb +33 -0
  42. data/test/client/warmer_test.rb +56 -0
  43. data/test/client_test.rb +86 -0
  44. data/test/core_ext/time_test.rb +46 -0
  45. data/test/middleware/encode_json_test.rb +53 -0
  46. data/test/middleware/opaque_id_test.rb +39 -0
  47. data/test/middleware/parse_json_test.rb +54 -0
  48. data/test/test_helper.rb +94 -0
  49. metadata +210 -0
@@ -0,0 +1,407 @@
1
+ module Elastomer
2
+ class Client
3
+
4
+ # Provides access to index-level API commands.
5
+ #
6
+ # name - The name of the index as a String or an Array of names
7
+ #
8
+ # Returns an Index instance.
9
+ def index( name )
10
+ Index.new self, name
11
+ end
12
+
13
+ class Index
14
+ # Create a new index client for making API requests that pertain to
15
+ # the health and management individual indexes.
16
+ #
17
+ # client - Elastomer::Client used for HTTP requests to the server
18
+ # name - The name of the index as a String or an Array of names
19
+ #
20
+ def initialize( client, name )
21
+ @client = client
22
+ @name = @client.assert_param_presence(name, 'index name')
23
+ end
24
+
25
+ attr_reader :client, :name
26
+
27
+ # Check for the existence of the index. If a :type option is given, then
28
+ # we will check for the existence of the document type in the index.
29
+ #
30
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-indices-exists/
31
+ # and http://www.elasticsearch.org/guide/reference/api/admin-indices-types-exists/
32
+ #
33
+ # params - Parameters Hash
34
+ #
35
+ # Returns true if the index (or type) exists
36
+ def exists?( params = {} )
37
+ response = client.head '/{index}{/type}', update_params(params, :action => 'index.exists')
38
+ response.success?
39
+ end
40
+ alias :exist? :exists?
41
+
42
+ # Create the index.
43
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-create-index/
44
+ #
45
+ # body - The index settings and mappings as a Hash or a JSON encoded String
46
+ # params - Parameters Hash
47
+ #
48
+ # Returns the response body as a Hash
49
+ def create( body, params = {} )
50
+ response = client.post '/{index}', update_params(params, :body => body, :action => 'index.create')
51
+ response.body
52
+ end
53
+
54
+ # Delete the index.
55
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-index/
56
+ #
57
+ # params - Parameters Hash
58
+ #
59
+ # Returns the response body as a Hash
60
+ def delete( params = {} )
61
+ response = client.delete '/{index}', update_params(params, :action => 'index.delete')
62
+ response.body
63
+ end
64
+
65
+ # Open the index.
66
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-open-close/
67
+ #
68
+ # params - Parameters Hash
69
+ #
70
+ # Returns the response body as a Hash
71
+ def open( params = {} )
72
+ response = client.post '/{index}/_open', update_params(params, :action => 'index.open')
73
+ response.body
74
+ end
75
+
76
+ # Close the index.
77
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-open-close/
78
+ #
79
+ # params - Parameters Hash
80
+ #
81
+ # Returns the response body as a Hash
82
+ def close( params = {} )
83
+ response = client.post '/{index}/_close', update_params(params, :action => 'index.close')
84
+ response.body
85
+ end
86
+
87
+ # Retrieve the settings for the index.
88
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-get-settings/
89
+ #
90
+ # params - Parameters Hash
91
+ #
92
+ # Returns the response body as a Hash
93
+ def get_settings( params = {} )
94
+ response = client.get '{/index}/_settings', update_params(params, :action => 'index.get_settings')
95
+ response.body
96
+ end
97
+ alias :settings :get_settings
98
+
99
+ # Change specific index level settings in real time.
100
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-update-settings/
101
+ #
102
+ # body - The index settings as a Hash or a JSON encoded String
103
+ # params - Parameters Hash
104
+ #
105
+ # Returns the response body as a Hash
106
+ def update_settings( body, params = {} )
107
+ response = client.put '{/index}/_settings', update_params(params, :body => body, :action => 'index.update_settings')
108
+ response.body
109
+ end
110
+
111
+ # Retrive one or more mappings from the index. To retrieve a specific
112
+ # mapping provide the name as the :type parameter.
113
+ #
114
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-get-mapping/
115
+ #
116
+ # params - Parameters Hash
117
+ #
118
+ # Returns the response body as a Hash
119
+ def mapping( params = {} )
120
+ response = client.get '/{index}{/type}/_mapping', update_params(params, :action => 'index.mapping')
121
+ response.body
122
+ end
123
+
124
+ # Register specific mapping definition for a specific type.
125
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-put-mapping/
126
+ #
127
+ # type - Name of the mapping to update as a String
128
+ # body - The mapping values to update as a Hash or a JSON encoded String
129
+ # params - Parameters Hash
130
+ #
131
+ # Returns the response body as a Hash
132
+ def update_mapping( type, body, params = {} )
133
+ response = client.put '/{index}/{type}/_mapping', update_params(params, :body => body, :type => type, :action => 'index.update_mapping')
134
+ response.body
135
+ end
136
+ alias :put_mapping :update_mapping
137
+
138
+ # Delete the mapping identified by `type`. This deletes all documents of
139
+ # that type from the index.
140
+ #
141
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-delete-mapping/
142
+ #
143
+ # type - Name of the mapping to update as a String
144
+ # params - Parameters Hash
145
+ #
146
+ # Returns the response body as a Hash
147
+ def delete_mapping( type, params = {} )
148
+ response = client.delete '/{index}/{type}', update_params(params, :type => type, :action => 'index.delete_mapping')
149
+ response.body
150
+ end
151
+
152
+ # Return the aliases associated with this index.
153
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-aliases/
154
+ #
155
+ # params - Parameters Hash
156
+ #
157
+ # Returns the response body as a Hash
158
+ def get_aliases( params = {} )
159
+ response = client.get '/{index}/_aliases', update_params(:action => 'index.get_aliases')
160
+ response.body
161
+ end
162
+ alias :aliases :get_aliases
163
+
164
+ # Performs the analysis process on a text and return the tokens breakdown of the text.
165
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-analyze/
166
+ #
167
+ # text - The text to analyze as a String
168
+ # params - Parameters Hash
169
+ #
170
+ # Returns the response body as a Hash
171
+ def analyze( text, params = {} )
172
+ response = client.get '{/index}/_analyze', update_params(params, :body => text.to_s, :action => 'index.analyze')
173
+ response.body
174
+ end
175
+
176
+ # Explicitly refresh one or more index, making all operations performed
177
+ # since the last refresh available for search.
178
+ #
179
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-refresh/
180
+ #
181
+ # params - Parameters Hash
182
+ #
183
+ # Returns the response body as a Hash
184
+ def refresh( params = {} )
185
+ response = client.post '{/index}/_refresh', update_params(params, :action => 'index.refresh')
186
+ response.body
187
+ end
188
+
189
+ # Flush one or more indices to the index storage.
190
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-flush/
191
+ #
192
+ # params - Parameters Hash
193
+ #
194
+ # Returns the response body as a Hash
195
+ def flush( params = {} )
196
+ response = client.post '{/index}/_flush', update_params(params, :action => 'index.flush')
197
+ response.body
198
+ end
199
+
200
+ # Optimize one or more indices. Optimizing an index allows for faster
201
+ # search operations but can be resource intensive.
202
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-optimize/
203
+ #
204
+ # params - Parameters Hash
205
+ #
206
+ # Returns the response body as a Hash
207
+ def optimize( params = {} )
208
+ response = client.post '{/index}/_optimize', update_params(params, :action => 'index.optimize')
209
+ response.body
210
+ end
211
+
212
+ # Deprecated: Explicitly snapshot (backup) one or more indices to the
213
+ # gateway. By default this happens periodically (every 1 second) but the
214
+ # period can be changed or disabled completely.
215
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-gateway-snapshot/
216
+ #
217
+ # This API was removed in ES 1.2.
218
+ #
219
+ # params - Parameters Hash
220
+ #
221
+ # Returns the response body as a Hash
222
+ def snapshot( params = {} )
223
+ response = client.post '{/index}/_gateway/snapshot', update_params(params, :action => 'index.snapshot')
224
+ response.body
225
+ end
226
+
227
+ # Clear caches for one or more indices. Individual caches can be
228
+ # specified with parameters.
229
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-clearcache/
230
+ #
231
+ # params - Parameters Hash
232
+ #
233
+ # Returns the response body as a Hash
234
+ def clear_cache( params = {} )
235
+ response = client.post '{/index}/_cache/clear', update_params(params, :action => 'index.clear_cache')
236
+ response.body
237
+ end
238
+
239
+ # Retrieve statistics about one or more indices. Specific statistics
240
+ # can be retrieved with parameters.
241
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-stats/
242
+ #
243
+ # params - Parameters Hash
244
+ #
245
+ # Returns the response body as a Hash
246
+ def stats( params = {} )
247
+ response = client.get '{/index}/_stats', update_params(params, :action => 'index.stats')
248
+ response.body
249
+ end
250
+
251
+ # Retrieve the status of one or more indices. Recovery and snapshot
252
+ # status can be retrieved with parameters.
253
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-status/
254
+ #
255
+ # params - Parameters Hash
256
+ #
257
+ # Returns the response body as a Hash
258
+ def status( params = {} )
259
+ response = client.get '{/index}/_status', update_params(params, :action => 'index.status')
260
+ response.body
261
+ end
262
+
263
+ # Retrieve low level Lucene segments information for shards of one
264
+ # or more indices.
265
+ # See http://www.elasticsearch.org/guide/reference/api/admin-indices-segments/
266
+ #
267
+ # params - Parameters Hash
268
+ #
269
+ # Returns the response body as a Hash
270
+ def segments( params = {} )
271
+ response = client.get '{/index}/_segments', update_params(params, :action => 'index.segments')
272
+ response.body
273
+ end
274
+
275
+ # Provides access to document-level API commands. These commands will be
276
+ # scoped to this index and the give `type`, if any.
277
+ #
278
+ # type - The document type as a String
279
+ #
280
+ # Returns a Docs instance.
281
+ def docs( type = nil )
282
+ client.docs name, type
283
+ end
284
+
285
+ # Perform bulk indexing and/or delete operations. The current index name
286
+ # will be passed to the bulk API call as part of the request parameters.
287
+ #
288
+ # params - Parameters Hash that will be passed to the bulk API call.
289
+ # block - Required block that is used to accumulate bulk API operations.
290
+ # All the operations will be passed to the search cluster via a
291
+ # single API request.
292
+ #
293
+ # Yields a Bulk instance for building bulk API call bodies.
294
+ #
295
+ # Examples
296
+ #
297
+ # index.bulk do |b|
298
+ # b.index( document1 )
299
+ # b.index( document2 )
300
+ # b.delete( document3 )
301
+ # ...
302
+ # end
303
+ #
304
+ # Returns the response body as a Hash
305
+ def bulk( params = {}, &block )
306
+ raise 'a block is required' if block.nil?
307
+
308
+ params = {:index => self.name}.merge params
309
+ client.bulk params, &block
310
+ end
311
+
312
+ # Create a new Scan instance for scrolling all results from a `query`.
313
+ # The Scan will be scoped to the current index.
314
+ #
315
+ # query - The query to scan as a Hash or a JSON encoded String
316
+ # opts - Options Hash
317
+ # :index - the name of the index to search
318
+ # :type - the document type to search
319
+ # :scroll - the keep alive time of the scrolling request (5 minutes by default)
320
+ # :size - the number of documents per shard to fetch per scroll
321
+ #
322
+ # Examples
323
+ #
324
+ # scan = index.scan('{"query":{"match_all":{}}}')
325
+ # scan.each_document do |document|
326
+ # document['_id']
327
+ # document['_source']
328
+ # end
329
+ #
330
+ # Returns a new Scan instance
331
+ def scan( query, opts = {} )
332
+ opts = {:index => name}.merge opts
333
+ client.scan query, opts
334
+ end
335
+
336
+ # Execute an array of searches in bulk. Results are returned in an
337
+ # array in the order the queries were sent. The current index name
338
+ # will be passed to the multi_search API call as part of the request
339
+ # parameters.
340
+ #
341
+ # See http://www.elasticsearch.org/guide/reference/api/multi-search/
342
+ #
343
+ # params - Parameters Hash that will be passed to the API call.
344
+ # block - Required block that is used to accumulate searches.
345
+ # All the operations will be passed to the search cluster
346
+ # via a single API request.
347
+ #
348
+ # Yields a MultiSearch instance for building multi_search API call
349
+ # bodies.
350
+ #
351
+ # Examples
352
+ #
353
+ # index.multi_search do |m|
354
+ # m.search({:query => {:match_all => {}}, :search_type => :count)
355
+ # m.search({:query => {:field => {"author" => "grantr"}}}, :type => 'tweet')
356
+ # ...
357
+ # end
358
+ #
359
+ # Returns the response body as a Hash
360
+ def multi_search( params = {}, &block )
361
+ raise 'a block is required' if block.nil?
362
+
363
+ params = {:index => self.name}.merge params
364
+ client.multi_search params, &block
365
+ end
366
+
367
+ # Provides access to warmer API commands. Index warmers run search
368
+ # requests to warm up the index before it is available for
369
+ # searching. Warmers are useful for searches that require heavy
370
+ # data loading, such as faceting or sorting.
371
+ #
372
+ # The warmer api allows creating, deleting, and retrieving
373
+ # registered warmers.
374
+ #
375
+ # warmer_name - The name of the warmer to operate on.
376
+ #
377
+ # Examples
378
+ # index.warmer('warmer1').create(:query => {:match_all => {}})
379
+ # index.warmer('warmer1').get
380
+ # index.warmer('warmer1').delete
381
+ #
382
+ # Returns a new Warmer instance
383
+ def warmer( warmer_name )
384
+ client.warmer(name, warmer_name)
385
+ end
386
+
387
+ # Internal: Add default parameters to the `params` Hash and then apply
388
+ # `overrides` to the params if any are given.
389
+ #
390
+ # params - Parameters Hash
391
+ # overrides - Optional parameter overrides as a Hash
392
+ #
393
+ # Returns a new params Hash.
394
+ def update_params( params, overrides = nil )
395
+ h = defaults.update params
396
+ h.update overrides unless overrides.nil?
397
+ h
398
+ end
399
+
400
+ # Internal: Returns a Hash containing default parameters.
401
+ def defaults
402
+ { :index => name }
403
+ end
404
+
405
+ end
406
+ end
407
+ end
@@ -0,0 +1,115 @@
1
+ module Elastomer
2
+ class Client
3
+
4
+ # Execute an array of searches in bulk. Results are returned in an
5
+ # array in the order the queries were sent.
6
+ #
7
+ # The `multi_search` method can be used in two ways. Without a block
8
+ # the method will perform an API call, and it requires a bulk request
9
+ # body and optional request parameters.
10
+ #
11
+ # See http://www.elasticsearch.org/guide/reference/api/multi-search/
12
+ #
13
+ # body - Request body as a String (required if a block is not given)
14
+ # params - Optional request parameters as a Hash
15
+ # block - Passed to a MultiSearch instance which assembles the searches
16
+ # into a single request.
17
+ #
18
+ # Examples
19
+ #
20
+ # # index and type in request body
21
+ # multi_search(request_body)
22
+ #
23
+ # # index in URI
24
+ # multi_search(request_body, :index => 'default-index')
25
+ #
26
+ # # block form
27
+ # multi_search(:index => 'default-index') do |m|
28
+ # m.search({:query => {:match_all => {}}, :search_type => :count)
29
+ # m.search({:query => {:field => {"foo" => "bar"}}}, :type => 'default-type')
30
+ # ...
31
+ # end
32
+ #
33
+ # Returns the response body as a Hash
34
+ def multi_search(body = nil, params = nil)
35
+ if block_given?
36
+ params, body = (body || {}), nil
37
+ yield msearch_obj = MultiSearch.new(self, params)
38
+ msearch_obj.call
39
+ else
40
+ raise 'multi_search request body cannot be nil' if body.nil?
41
+ params ||= {}
42
+
43
+ response = self.post '{/index}{/type}/_msearch', params.merge(:body => body)
44
+ response.body
45
+ end
46
+ end
47
+ alias :msearch :multi_search
48
+
49
+ # The MultiSearch class is a helper for accumulating and submitting
50
+ # multi_search API requests. Instances of the MultiSearch class
51
+ # accumulate searches and then issue a single API request to
52
+ # ElasticSearch, which runs all accumulated searches in parallel
53
+ # and returns each result hash aggregated into an array of result
54
+ # hashes.
55
+ #
56
+ # Instead of instantiating this class directly, use
57
+ # the block form of Client#multi_search.
58
+ #
59
+ class MultiSearch
60
+
61
+ # Create a new MultiSearch instance for accumulating searches and
62
+ # submitting them all as a single request.
63
+ #
64
+ # client - Elastomer::Client used for HTTP requests to the server
65
+ # params - Parameters Hash to pass to the Client#multi_search method
66
+ def initialize(client, params = {})
67
+ @client = client
68
+ @params = params
69
+
70
+ @actions = []
71
+ end
72
+
73
+ attr_reader :client
74
+
75
+ # Add a search to the multi search request. This search will not
76
+ # be executed until the multi_search API call is made.
77
+ #
78
+ # query - The query body as a Hash
79
+ # params - Parameters Hash
80
+ #
81
+ # Returns this MultiSearch instance.
82
+ def search(query, params = {})
83
+ add_to_actions(params)
84
+ add_to_actions(query)
85
+ end
86
+
87
+ # Execute the multi_search call with the accumulated searches. If
88
+ # the accumulated actions list is empty then no action is taken.
89
+ #
90
+ # Returns the response body Hash.
91
+ def call
92
+ return if @actions.empty?
93
+
94
+ body = @actions.join("\n") + "\n"
95
+ client.multi_search(body, @params)
96
+ ensure
97
+ @actions.clear
98
+ end
99
+
100
+ # Internal: Add an action to the pending request. Actions can be
101
+ # either search params or query bodies. The first action must be
102
+ # a search params hash, followed by a query body, then alternating
103
+ # params and queries.
104
+ #
105
+ # action - the Hash (params or query) to add to the pending request
106
+ #
107
+ # Returns this MultiSearch instance.
108
+ def add_to_actions(action)
109
+ action = MultiJson.dump action
110
+ @actions << action
111
+ self
112
+ end
113
+ end
114
+ end
115
+ end