elastomer-client 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
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