algoliasearch 1.4.1 → 1.4.2

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
  SHA1:
3
- metadata.gz: d9df8ced9c8a5da4e7e677c2643b24891b84a406
4
- data.tar.gz: ea2d150a9d5171f5e4da18a6a5c7758137d31aa5
3
+ metadata.gz: f84aa6b108332e6d8c8e967371efe01ededbeff9
4
+ data.tar.gz: 89e4300df60f82e9a392f1179bdbcd0521e80cd0
5
5
  SHA512:
6
- metadata.gz: 04a47d4b5227e7e97db5d33fb1759a3c053e0e34a94fb6d7eb380c97a4ae4dbfc097df30755afa2524f41cc93400d19c2b3db5d70676cd9a5469ba68cadab3e4
7
- data.tar.gz: 088ba592a94f6e31dd3d0f07f5668b53bb63932fd8680e84c03da0dc7a0add25aaa8a8bfca3f8c9b43ec797d0288391611ec441f89d0bfa77a188de3ffbfdbd8
6
+ metadata.gz: 57b4c7a292ff76a4686da1e74f42c5f51be1ee96bf98bcd9dfb2725570cb4b5edee355f44a0f6ad0861226ed6df906e5c9ac0a645b77754c98b6c01e78b46caa
7
+ data.tar.gz: 6b40a8311c4037fe9b00a6e8242146dcab7e2be3bc605a311206b2613f3c045d46ad9dd2df0d473b58a4c49ca7a37c18a158f194a71c075058e9e8e4122f5c94
data/ChangeLog CHANGED
@@ -1,5 +1,11 @@
1
1
  CHANGELOG
2
2
 
3
+ 2015-05-04 1.4.2
4
+ * Add new methods to add/update api key
5
+ * Add batch method to target multiple indices
6
+ * Add strategy parameter for the multipleQueries
7
+ * Add new method to generate secured api key from query parameters
8
+
3
9
  2015-04-10 1.4.1
4
10
  * Force the default connect/read/write/search/batch timeouts to Algolia-specific values
5
11
 
data/README.md CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
 
4
4
 
5
+
5
6
  [Algolia Search](http://www.algolia.com) is a hosted full-text, numerical, and faceted search engine capable of delivering realtime results from the first keystroke.
6
7
 
7
8
  Our Ruby client lets you easily use the [Algolia Search API](https://www.algolia.com/doc/rest_api) from your backend. It wraps the [Algolia Search REST API](http://www.algolia.com/doc/rest_api).
@@ -23,9 +24,10 @@ Table of Contents
23
24
 
24
25
  **Commands Reference**
25
26
 
26
- 1. [Add a new object](#add-a-new-object-in-the-index)
27
+ 1. [Add a new object](#add-a-new-object-to-the-index)
27
28
  1. [Update an object](#update-an-existing-object-in-the-index)
28
29
  1. [Search](#search)
30
+ 1. [Multiple queries](#multiple-queries)
29
31
  1. [Get an object](#get-an-object)
30
32
  1. [Delete an object](#delete-an-object)
31
33
  1. [Delete by query](#delete-by-query)
@@ -37,13 +39,12 @@ Table of Contents
37
39
  1. [Batch writes](#batch-writes)
38
40
  1. [Security / User API Keys](#security--user-api-keys)
39
41
  1. [Copy or rename an index](#copy-or-rename-an-index)
40
- 1. [Backup / Retrieve all index content](#backup--retrieve-all-index-content)
42
+ 1. [Backup / Retrieve all index content](#backup--retrieve-of-all-index-content)
41
43
  1. [Logs](#logs)
42
44
  1. [Mock](#mock)
43
45
 
44
46
 
45
47
 
46
-
47
48
  Setup
48
49
  -------------
49
50
  To setup your project, follow these steps:
@@ -68,15 +69,10 @@ If you're a Ruby on Rails user; you're probably looking for the [algoliasearch-r
68
69
 
69
70
 
70
71
 
71
-
72
-
73
-
74
-
75
-
76
-
77
72
  Quick Start
78
73
  -------------
79
74
 
75
+
80
76
  In 30 seconds, this quick start tutorial will show you how to index and search objects.
81
77
 
82
78
  Without any prior configuration, you can start indexing [500 contacts](https://github.com/algolia/algoliasearch-client-csharp/blob/master/contacts.json) in the ```contacts``` index using the following code:
@@ -123,7 +119,7 @@ puts index.search('jim').to_json
123
119
  ```html
124
120
  <script src="//cdn.jsdelivr.net/algoliasearch/3/algoliasearch.min.js"></script>
125
121
  <script>
126
- var client = algoliasearch('ApplicationID', 'Search-Only-API-Key');
122
+ var client = algoliasearch('ApplicationID', 'apiKey');
127
123
  var index = client.initIndex('indexName');
128
124
 
129
125
  // perform query "jim"
@@ -153,13 +149,8 @@ function searchCallback(err, content) {
153
149
 
154
150
 
155
151
 
156
-
157
-
158
-
159
-
160
152
  Documentation
161
153
  ================
162
-
163
154
  Check our [online documentation](http://www.algolia.com/doc/guides/ruby):
164
155
  * [Initial Import](http://www.algolia.com/doc/guides/ruby#InitialImport)
165
156
  * [Ranking &amp; Relevance](http://www.algolia.com/doc/guides/ruby#RankingRelevance)
@@ -172,7 +163,6 @@ Check our [online documentation](http://www.algolia.com/doc/guides/ruby):
172
163
  * [Security](http://www.algolia.com/doc/guides/ruby#Security)
173
164
  * [REST API](http://www.algolia.com/doc/rest)
174
165
 
175
-
176
166
  Tutorials
177
167
  ================
178
168
 
@@ -188,8 +178,6 @@ Commands Reference
188
178
 
189
179
 
190
180
 
191
-
192
-
193
181
  Add a new object to the Index
194
182
  -------------
195
183
 
@@ -286,8 +274,6 @@ index.partial_update_object({"price" => {"value" => 42, "_operation": "Decrement
286
274
  "objectID" => "myID"})
287
275
  ```
288
276
 
289
-
290
-
291
277
  Search
292
278
  -------------
293
279
 
@@ -437,6 +423,10 @@ res = Algolia.multiple_queries([{:index_name => "categories", "query" => my_quer
437
423
  puts res["results"]
438
424
  ```
439
425
 
426
+ You can specify a strategy to optimize your multiple queries:
427
+ - **none**: Execute the sequence of queries until the end.
428
+ - **stopIfEnoughMatches**: Execute the sequence of queries until the number of hits is reached by the sum of hits.
429
+
440
430
 
441
431
 
442
432
  Get an object
@@ -455,16 +445,10 @@ res = index.get_object("myID", "fistname")
455
445
 
456
446
  You can also retrieve a set of objects:
457
447
 
458
-
459
448
  ```ruby
460
449
  res = index.get_objects(["myID", "myID2"])
461
450
  ```
462
451
 
463
-
464
-
465
-
466
-
467
-
468
452
  Delete an object
469
453
  -------------
470
454
 
@@ -496,8 +480,8 @@ You can retrieve all settings using the `get_settings` function. The result will
496
480
  * **attributesToIndex**: (array of strings) The list of fields you want to index.<br/>If set to null, all textual and numerical attributes of your objects are indexed. Be sure to update it to get optimal results.<br/>This parameter has two important uses:
497
481
  * *Limit the attributes to index*.<br/>For example, if you store a binary image in base64, you want to store it and be able to retrieve it, but you don't want to search in the base64 string.
498
482
  * *Control part of the ranking*.<br/>(see the ranking parameter for full explanation) Matches in attributes at the beginning of the list will be considered more important than matches in attributes further down the list. In one attribute, matching text at the beginning of the attribute will be considered more important than text after. You can disable this behavior if you add your attribute inside `unordered(AttributeName)`. For example, `attributesToIndex: ["title", "unordered(text)"]`.
499
- **Notes**: All numerical attributes are automatically indexed as numerical filters. If you don't need filtering on some of your numerical attributes, please consider sending them as strings to speed up the indexing.<br/>
500
483
  You can decide to have the same priority for two attributes by passing them in the same string using a comma as a separator. For example `title` and `alternative_title` have the same priority in this example, which is different than text priority: `attributesToIndex:["title,alternative_title", "text"]`.
484
+ * **numericAttributesToIndex**: (array of strings) All numerical attributes are automatically indexed as numerical filters. If you don't need filtering on some of your numerical attributes, you can specify this list to speed up the indexing.<br/> If you only need to filter on a numeric value with the operator '=', you can speed up the indexing by specifying the attribute with `equalOnly(AttributeName)`. The other operators will be disabled.
501
485
  * **attributesForFaceting**: (array of strings) The list of fields you want to use for faceting. All strings in the attribute selected for faceting are extracted and added as a facet. If set to null, no attribute is used for faceting.
502
486
  * **attributeForDistinct**: The attribute name used for the `Distinct` feature. This feature is similar to the SQL "distinct" keyword. When enabled in queries with the `distinct=1` parameter, all hits containing a duplicate value for this attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and others are removed. **Note**: This feature is disabled if the query string is empty and there aren't any `tagFilters`, `facetFilters`, nor `numericFilters` parameters.
503
487
  * **ranking**: (array of strings) Controls the way results are sorted.<br/>We have nine available criteria:
@@ -523,7 +507,7 @@ You can decide to have the same priority for two attributes by passing them in t
523
507
  * **allowCompressionOfIntegerArray**: Allows compression of big integer arrays. We recommended enabling this feature and then storing the list of user IDs or rights as an integer array. When enabled, the integer array is reordered to reach a better compression ratio. Defaults to false.
524
508
 
525
509
  #### Query expansion
526
- * **synonyms**: (array of array of words considered as equals). For example, you may want to retrieve the **black ipad** record when your users are searching for **dark ipad**, even if the word **dark** is not part of the record. To do this, you need to configure **black** as a synonym of **dark**. For example, `"synomyms": [ [ "black", "dark" ], [ "small", "little", "mini" ], ... ]`.
510
+ * **synonyms**: (array of array of string considered as equals). For example, you may want to retrieve the **black ipad** record when your users are searching for **dark ipad**, even if the word **dark** is not part of the record. To do this, you need to configure **black** as a synonym of **dark**. For example, `"synomyms": [ [ "black", "dark" ], [ "small", "little", "mini" ], ... ]`. Synonym feature also supports multi-words expression like `"synonyms": [ ["NY", "New York"] ]`
527
511
  * **placeholders**: (hash of array of words). This is an advanced use case to define a token substitutable by a list of words without having the original token searchable. It is defined by a hash associating placeholders to lists of substitutable words. For example, `"placeholders": { "<streetnumber>": ["1", "2", "3", ..., "9999"]}` would allow it to be able to match all street numbers. We use the `< >` tag syntax to define placeholders in an attribute. For example:
528
512
  * Push a record with the placeholder: `{ "name" : "Apple Store", "address" : "&lt;streetnumber&gt; Opera street, Paris" }`.
529
513
  * Configure the placeholder in your index settings: `"placeholders": { "<streetnumber>" : ["1", "2", "3", "4", "5", ... ], ... }`.
@@ -639,6 +623,23 @@ res = index.partial_update_objects([{"firstname" => "Jimmie",
639
623
 
640
624
 
641
625
 
626
+ If you have one index per user, you may want to perform a batch operations across severals indexes.
627
+ We expose a method to perform this type of batch:
628
+ ```ruby
629
+ res = index.batch([
630
+ {"action"=> "addObject", "indexName"=> "index1", "body": {"firstname" => "Jimmie",
631
+ "lastname" => "Barninger"}},
632
+ {"action"=> "addObject", "indexName"=> "index2", "body": {"firstname" => "Warren",
633
+ "lastname" => "Speach"}}])
634
+ ```
635
+
636
+ The attribute **action** can have these values:
637
+ - addObject
638
+ - updateObject
639
+ - partialUpdateObject
640
+ - partialUpdateObjectNoCreate
641
+ - deleteObject
642
+
642
643
  Security / User API Keys
643
644
  -------------
644
645
 
@@ -675,7 +676,7 @@ res = index.add_user_key(["search"])
675
676
  puts res['key']
676
677
  ```
677
678
 
678
- You can also create an API Key with advanced restrictions:
679
+ You can also create an API Key with advanced settings:
679
680
 
680
681
  * Add a validity period. The key will be valid for a specific period of time (in seconds).
681
682
  * Specify the maximum number of API calls allowed from an IP address per hour. Each time an API call is performed with this key, a check is performed. If the IP at the source of the call did more than this number of calls in the last hour, a 403 code is returned. Defaults to 0 (no rate limit). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
@@ -685,6 +686,10 @@ You can also create an API Key with advanced restrictions:
685
686
 
686
687
  * Specify the maximum number of hits this API key can retrieve in one call. Defaults to 0 (unlimited). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
687
688
  * Specify the list of targeted indices. You can target all indices starting with a prefix or ending with a suffix using the '*' character. For example, "dev_*" matches all indices starting with "dev_" and "*_dev" matches all indices ending with "_dev". Defaults to all indices if empty or blank.
689
+ * Specify the list of referers. You can target all referers starting with a prefix or ending with a suffix using the '*' character. For example, "algolia.com/*" matches all referers starting with "algolia.com/" and "*.algolia.com" matches all referers ending with ".algolia.com". Defaults to all referers if empty or blank.
690
+ * Specify the list of query parameters. You can force the query parameters for a query using the url string format (param1=X&param2=Y...).
691
+ * Specify a description to describe where the key is used.
692
+
688
693
 
689
694
  ```ruby
690
695
  # Creates a new global API key that is valid for 300 seconds
@@ -695,7 +700,18 @@ puts res['key']
695
700
  # - rate limit of 100 calls per hour per IP
696
701
  # - maximum of 20 hits
697
702
  # - valid on 'my_index1' and 'my_index2'
698
- res = index.add_user_key(["search"], 300, 100, 20, ['my_index1', 'my_index2'])
703
+
704
+ params = {
705
+ :validity => 300,
706
+ :maxQueriesPerIPPerHour => 100,
707
+ :maxHitsPerQuery => 20,
708
+ :indexes => ['my_index1', 'my_index2'],
709
+ :referers => ['algolia.com/*'],
710
+ :queryParameters => 'typoTolerance=strict&ignorePlurals=false',
711
+ :description => 'Limited search only API key for algolia.com'
712
+ }
713
+
714
+ res = Algolia.add_user_key(params)
699
715
  puts res['key']
700
716
  ```
701
717
 
@@ -730,21 +746,19 @@ index.delete_user_key("71671c38001bf3ac857bc82052485107")
730
746
 
731
747
 
732
748
 
733
- You may have a single index containing per user data. In that case, all records should be tagged with their associated user_id in order to add a `tagFilters=(public,user_42)` filter at query time to retrieve only what a user has access to. If you're using the [JavaScript client](http://github.com/algolia/algoliasearch-client-js), it will result in a security breach since the user is able to modify the `tagFilters` you've set by modifying the code from the browser. To keep using the JavaScript client (recommended for optimal latency) and target secured records, you can generate a secured API key from your backend:
749
+ You may have a single index containing per user data. In that case, all records should be tagged with their associated user_id in order to add a `tagFilters=user_42` filter at query time to retrieve only what a user has access to. If you're using the [JavaScript client](http://github.com/algolia/algoliasearch-client-js), it will result in a security breach since the user is able to modify the `tagFilters` you've set by modifying the code from the browser. To keep using the JavaScript client (recommended for optimal latency) and target secured records, you can generate a secured API key from your backend:
734
750
 
735
751
  ```ruby
736
752
  # generate a public API key for user 42. Here, records are tagged with:
737
- # - 'public' if they are visible by all users
738
753
  # - 'user_XXXX' if they are visible by user XXXX
739
- public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', '(public,user_42)'
754
+ public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', 'tagFilters=user_42'
740
755
  ```
741
756
 
742
757
  This public API key can then be used in your JavaScript code as follow:
743
758
 
744
- ```javascript
745
- <script type="text/javascript">
759
+ ```js
746
760
  var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
747
- client.setSecurityTags('(public,user_42)'); // must be same than those used at generation-time
761
+ client.setExtraHeader('X-Algolia-QueryParameters', 'tagFilters=user_42'); // must be same than those used at generation-time
748
762
 
749
763
  var index = client.initIndex('indexName')
750
764
 
@@ -756,26 +770,23 @@ index.search('something', function(err, content) {
756
770
 
757
771
  console.log(content);
758
772
  });
759
- </script>
760
773
  ```
761
774
 
762
775
  You can mix rate limits and secured API keys by setting an extra `user_token` attribute both at API key generation time and query time. When set, a unique user will be identified by her `IP + user_token` instead of only by her `IP`. This allows you to restrict a single user to performing a maximum of `N` API calls per hour, even if she shares her `IP` with another user.
763
776
 
764
777
  ```ruby
765
778
  # generate a public API key for user 42. Here, records are tagged with:
766
- # - 'public' if they are visible by all users
767
779
  # - 'user_XXXX' if they are visible by user XXXX
768
- public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', '(public,user_42)', 'user_42'
780
+ public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', 'tagFilters=user_42', 'user_42'
769
781
  ```
770
782
 
771
783
  This public API key can then be used in your JavaScript code as follow:
772
784
 
773
- ```javascript
774
- <script type="text/javascript">
785
+ ```js
775
786
  var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
776
787
 
777
788
  // must be same than those used at generation-time
778
- client.setSecurityTags('(public,user_42)');
789
+ client.setExtraHeader('X-Algolia-QueryParameters', 'tagFilters=user_42');
779
790
 
780
791
  // must be same than the one used at generation-time
781
792
  client.setUserToken('user_42');
@@ -790,7 +801,26 @@ index.search('another query', function(err, content) {
790
801
 
791
802
  console.log(content);
792
803
  });
793
- </script>
804
+ ```
805
+
806
+ You can also generate secured API keys to limit the usage of a key to a referer. The generation use the same function than the Per user restriction. This public API key can be used in your JavaScript code as follow:
807
+
808
+ ```js
809
+ var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
810
+
811
+ // must be same than those used at generation-time
812
+ client.setExtraHeader('X-Algolia-AllowedReferer', 'algolia.com/*');
813
+
814
+ var index = client.initIndex('indexName')
815
+
816
+ index.search('another query', function(err, content) {
817
+ if (err) {
818
+ console.error(err);
819
+ return;
820
+ }
821
+
822
+ console.log(content);
823
+ });
794
824
  ```
795
825
 
796
826
 
@@ -892,4 +922,3 @@ end
892
922
  ```
893
923
 
894
924
 
895
-
@@ -65,7 +65,7 @@ module Algolia
65
65
  begin
66
66
  return perform_request(host[:session], host[:base_url] + uri, method, data)
67
67
  rescue AlgoliaProtocolError => e
68
- raise if e.code == Protocol::ERROR_BAD_REQUEST or e.code == Protocol::ERROR_FORBIDDEN or e.code == Protocol::ERROR_NOT_FOUND
68
+ raise if e.code / 100 == 4
69
69
  exceptions << e
70
70
  rescue => e
71
71
  exceptions << e
@@ -129,7 +129,7 @@ module Algolia
129
129
  when :DELETE
130
130
  session.delete(url, { :header => @headers })
131
131
  end
132
- if response.code >= 400 || response.code < 200
132
+ if response.code / 100 != 2
133
133
  raise AlgoliaProtocolError.new(response.code, "Cannot #{method} to #{url}: #{response.content} (#{response.code})")
134
134
  end
135
135
  return JSON.parse(response.content)
@@ -220,8 +220,9 @@ module Algolia
220
220
  #
221
221
  # @param queries the array of hash representing the query and associated index name
222
222
  # @param index_name_key the name of the key used to fetch the index_name (:index_name by default)
223
+ # @param strategy define the strategy applied on the sequential searches (none by default)
223
224
  #
224
- def Algolia.multiple_queries(queries, index_name_key = :index_name)
225
+ def Algolia.multiple_queries(queries, index_name_key = :index_name, strategy = "none")
225
226
  requests = {
226
227
  :requests => queries.map do |query|
227
228
  indexName = query.delete(index_name_key) || query.delete(index_name_key.to_s)
@@ -229,7 +230,7 @@ module Algolia
229
230
  { :indexName => indexName, :params => Protocol.to_query(encoded_params) }
230
231
  end
231
232
  }
232
- Algolia.client.post(Protocol.multiple_queries_uri, requests.to_json, :search)
233
+ Algolia.client.post(Protocol.multiple_queries_uri(strategy), requests.to_json, :search)
233
234
  end
234
235
 
235
236
  #
@@ -326,27 +327,47 @@ module Algolia
326
327
  #
327
328
  # Create a new user key
328
329
  #
329
- # @param acls the list of ACL for this key. Defined by an array of strings that
330
- # can contains the following values:
331
- # - search: allow to search (https and http)
332
- # - addObject: allows to add a new object in the index (https only)
333
- # - updateObject : allows to change content of an existing object (https only)
334
- # - deleteObject : allows to delete an existing object (https only)
335
- # - deleteIndex : allows to delete index content (https only)
336
- # - settings : allows to get index settings (https only)
337
- # - editSettings : allows to change index settings (https only)
330
+ # @param obj can be two different parameters:
331
+ # The list of parameters for this key. Defined by a NSDictionary that
332
+ # can contains the following values:
333
+ # - acl: array of string
334
+ # - indices: array of string
335
+ # - validity: int
336
+ # - referers: array of string
337
+ # - description: string
338
+ # - maxHitsPerQuery: integer
339
+ # - queryParameters: string
340
+ # - maxQueriesPerIPPerHour: integer
341
+ # Or the list of ACL for this key. Defined by an array of NSString that
342
+ # can contains the following values:
343
+ # - search: allow to search (https and http)
344
+ # - addObject: allows to add/update an object in the index (https only)
345
+ # - deleteObject : allows to delete an existing object (https only)
346
+ # - deleteIndex : allows to delete index content (https only)
347
+ # - settings : allows to get index settings (https only)
348
+ # - editSettings : allows to change index settings (https only)
338
349
  # @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
339
350
  # @param maxQueriesPerIPPerHour the maximum number of API calls allowed from an IP address per hour (0 means unlimited)
340
351
  # @param maxHitsPerQuery the maximum number of hits this API key can retrieve in one call (0 means unlimited)
341
352
  # @param indexes the optional list of targeted indexes
342
353
  #
343
- def Algolia.add_user_key(acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0, indexes = nil)
344
- params = {
345
- :acl => acls,
346
- :validity => validity.to_i,
347
- :maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i,
348
- :maxHitsPerQuery => maxHitsPerQuery.to_i
349
- }
354
+ def Algolia.add_user_key(obj, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0, indexes = nil)
355
+ if obj.instance_of? Array
356
+ params = {
357
+ :acl => obj
358
+ }
359
+ else
360
+ params = obj
361
+ end
362
+ if validity != 0
363
+ params["validity"] = validity.to_i
364
+ end
365
+ if maxQueriesPerIPPerHour != 0
366
+ params["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour.to_i
367
+ end
368
+ if maxHitsPerQuery != 0
369
+ params["maxHitsPerQuery"] = maxHitsPerQuery.to_i
370
+ end
350
371
  params[:indexes] = indexes if indexes
351
372
  Algolia.client.post(Protocol.keys_uri, params.to_json)
352
373
  end
@@ -354,27 +375,47 @@ module Algolia
354
375
  #
355
376
  # Update a user key
356
377
  #
357
- # @param acls the list of ACL for this key. Defined by an array of strings that
358
- # can contains the following values:
359
- # - search: allow to search (https and http)
360
- # - addObject: allows to add a new object in the index (https only)
361
- # - updateObject : allows to change content of an existing object (https only)
362
- # - deleteObject : allows to delete an existing object (https only)
363
- # - deleteIndex : allows to delete index content (https only)
364
- # - settings : allows to get index settings (https only)
365
- # - editSettings : allows to change index settings (https only)
378
+ # @param obj can be two different parameters:
379
+ # The list of parameters for this key. Defined by a NSDictionary that
380
+ # can contains the following values:
381
+ # - acl: array of string
382
+ # - indices: array of string
383
+ # - validity: int
384
+ # - referers: array of string
385
+ # - description: string
386
+ # - maxHitsPerQuery: integer
387
+ # - queryParameters: string
388
+ # - maxQueriesPerIPPerHour: integer
389
+ # Or the list of ACL for this key. Defined by an array of NSString that
390
+ # can contains the following values:
391
+ # - search: allow to search (https and http)
392
+ # - addObject: allows to add/update an object in the index (https only)
393
+ # - deleteObject : allows to delete an existing object (https only)
394
+ # - deleteIndex : allows to delete index content (https only)
395
+ # - settings : allows to get index settings (https only)
396
+ # - editSettings : allows to change index settings (https only)
366
397
  # @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
367
398
  # @param maxQueriesPerIPPerHour the maximum number of API calls allowed from an IP address per hour (0 means unlimited)
368
399
  # @param maxHitsPerQuery the maximum number of hits this API key can retrieve in one call (0 means unlimited)
369
400
  # @param indexes the optional list of targeted indexes
370
401
  #
371
- def Algolia.update_user_key(key, acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0, indexes = nil)
372
- params = {
373
- :acl => acls,
374
- :validity => validity.to_i,
375
- :maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i,
376
- :maxHitsPerQuery => maxHitsPerQuery.to_i
377
- }
402
+ def Algolia.update_user_key(key, obj, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0, indexes = nil)
403
+ if obj.instance_of? Array
404
+ params = {
405
+ :acl => obj
406
+ }
407
+ else
408
+ params = obj
409
+ end
410
+ if validity != 0
411
+ params["validity"] = validity.to_i
412
+ end
413
+ if maxQueriesPerIPPerHour != 0
414
+ params["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour.to_i
415
+ end
416
+ if maxHitsPerQuery != 0
417
+ params["maxHitsPerQuery"] = maxHitsPerQuery.to_i
418
+ end
378
419
  params[:indexes] = indexes if indexes
379
420
  Algolia.client.put(Protocol.key_uri(key), params.to_json)
380
421
  end
@@ -385,6 +426,19 @@ module Algolia
385
426
  Algolia.client.delete(Protocol.key_uri(key))
386
427
  end
387
428
 
429
+ # Send a batch request targeting multiple indices
430
+ def Algolia.batch(requests)
431
+ Algolia.client.post(Protocol.batch_uri, {"requests" => requests}.to_json, :batch)
432
+ end
433
+
434
+ # Send a batch request targeting multiple indices and wait the end of the indexing
435
+ def Algolia.batch!(requests)
436
+ res = batch(requests)
437
+ res['taskID'].each { |index, taskID|
438
+ Algolia::Index.new(index).wait_task(taskID)
439
+ }
440
+ end
441
+
388
442
  # Used mostly for testing. Lets you delete the api key global vars.
389
443
  def Algolia.destroy
390
444
  @@client = Thread.current[:algolia_hosts] = Thread.current[:algolia_search_hosts] = nil
@@ -432,37 +432,91 @@ module Algolia
432
432
  #
433
433
  # Create a new user key
434
434
  #
435
- # @param acls the list of ACL for this key. Defined by an array of strings that
436
- # can contains the following values:
437
- # - search: allow to search (https and http)
438
- # - addObject: allows to add a new object in the index (https only)
439
- # - updateObject : allows to change content of an existing object (https only)
440
- # - deleteObject : allows to delete an existing object (https only)
441
- # - deleteIndex : allows to delete index content (https only)
442
- # - settings : allows to get index settings (https only)
443
- # - editSettings : allows to change index settings (https only)
435
+ # @param obj can be two different parameters:
436
+ # The list of parameters for this key. Defined by a NSDictionary that
437
+ # can contains the following values:
438
+ # - acl: array of string
439
+ # - validity: int
440
+ # - referers: array of string
441
+ # - description: string
442
+ # - maxHitsPerQuery: integer
443
+ # - queryParameters: string
444
+ # - maxQueriesPerIPPerHour: integer
445
+ # Or the list of ACL for this key. Defined by an array of NSString that
446
+ # can contains the following values:
447
+ # - search: allow to search (https and http)
448
+ # - addObject: allows to add/update an object in the index (https only)
449
+ # - deleteObject : allows to delete an existing object (https only)
450
+ # - deleteIndex : allows to delete index content (https only)
451
+ # - settings : allows to get index settings (https only)
452
+ # - editSettings : allows to change index settings (https only)
444
453
  # @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
454
+ # @param maxQueriesPerIPPerHour the maximum number of API calls allowed from an IP address per hour (0 means unlimited)
455
+ # @param maxHitsPerQuery the maximum number of hits this API key can retrieve in one call (0 means unlimited)
445
456
  #
446
- def add_user_key(acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
447
- Algolia.client.post(Protocol.index_keys_uri(name), {:acl => acls, :validity => validity, :maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i, :maxHitsPerQuery => maxHitsPerQuery.to_i}.to_json)
457
+ def add_user_key(obj, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
458
+ if obj.instance_of? Array
459
+ params = {
460
+ :acl => obj
461
+ }
462
+ else
463
+ params = obj
464
+ end
465
+ if validity != 0
466
+ params["validity"] = validity.to_i
467
+ end
468
+ if maxQueriesPerIPPerHour != 0
469
+ params["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour.to_i
470
+ end
471
+ if maxHitsPerQuery != 0
472
+ params["maxHitsPerQuery"] = maxHitsPerQuery.to_i
473
+ end
474
+ Algolia.client.post(Protocol.index_keys_uri(name), params.to_json)
448
475
  end
449
476
 
450
477
  #
451
478
  # Update a user key
452
479
  #
453
- # @param acls the list of ACL for this key. Defined by an array of strings that
454
- # can contains the following values:
455
- # - search: allow to search (https and http)
456
- # - addObject: allows to add a new object in the index (https only)
457
- # - updateObject : allows to change content of an existing object (https only)
458
- # - deleteObject : allows to delete an existing object (https only)
459
- # - deleteIndex : allows to delete index content (https only)
460
- # - settings : allows to get index settings (https only)
461
- # - editSettings : allows to change index settings (https only)
480
+ # @param obj can be two different parameters:
481
+ # The list of parameters for this key. Defined by a NSDictionary that
482
+ # can contains the following values:
483
+ # - acl: array of string
484
+ # - validity: int
485
+ # - referers: array of string
486
+ # - description: string
487
+ # - maxHitsPerQuery: integer
488
+ # - queryParameters: string
489
+ # - maxQueriesPerIPPerHour: integer
490
+ # Or the list of ACL for this key. Defined by an array of NSString that
491
+ # can contains the following values:
492
+ # - search: allow to search (https and http)
493
+ # - addObject: allows to add/update an object in the index (https only)
494
+ # - deleteObject : allows to delete an existing object (https only)
495
+ # - deleteIndex : allows to delete index content (https only)
496
+ # - settings : allows to get index settings (https only)
497
+ # - editSettings : allows to change index settings (https only)
462
498
  # @param validity the number of seconds after which the key will be automatically removed (0 means no time limit for this key)
499
+ # @param maxQueriesPerIPPerHour the maximum number of API calls allowed from an IP address per hour (0 means unlimited)
500
+ # @param maxHitsPerQuery the maximum number of hits this API key can retrieve in one call (0 means unlimited)
463
501
  #
464
- def update_user_key(key, acls, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
465
- Algolia.client.put(Protocol.index_key_uri(name, key), {:acl => acls, :validity => validity, :maxQueriesPerIPPerHour => maxQueriesPerIPPerHour.to_i, :maxHitsPerQuery => maxHitsPerQuery.to_i}.to_json)
502
+ def update_user_key(key, obj, validity = 0, maxQueriesPerIPPerHour = 0, maxHitsPerQuery = 0)
503
+ if obj.instance_of? Array
504
+ params = {
505
+ :acl => obj
506
+ }
507
+ else
508
+ params = obj
509
+ end
510
+ if validity != 0
511
+ params["validity"] = validity.to_i
512
+ end
513
+ if maxQueriesPerIPPerHour != 0
514
+ params["maxQueriesPerIPPerHour"] = maxQueriesPerIPPerHour.to_i
515
+ end
516
+ if maxHitsPerQuery != 0
517
+ params["maxHitsPerQuery"] = maxHitsPerQuery.to_i
518
+ end
519
+ Algolia.client.put(Protocol.index_key_uri(name, key), params.to_json)
466
520
  end
467
521
 
468
522
 
@@ -39,8 +39,8 @@ module Algolia
39
39
  "/#{VERSION}/indexes"
40
40
  end
41
41
 
42
- def Protocol.multiple_queries_uri
43
- "/#{VERSION}/indexes/*/queries"
42
+ def Protocol.multiple_queries_uri(strategy = "none")
43
+ "/#{VERSION}/indexes/*/queries?strategy=#{strategy}"
44
44
  end
45
45
 
46
46
  def Protocol.objects_uri
@@ -52,9 +52,9 @@ module Algolia
52
52
  "/#{VERSION}/indexes/#{CGI.escape(index)}"
53
53
  end
54
54
 
55
- def Protocol.batch_uri(index)
56
- "#{index_uri(index)}/batch"
57
- end
55
+ def Protocol.batch_uri(index = nil)
56
+ "#{index.nil? ? "/#{VERSION}/indexes/*" : index_uri(index)}/batch"
57
+ end
58
58
 
59
59
  def Protocol.index_operation_uri(index)
60
60
  "#{index_uri(index)}/operation"
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.4.1"
2
+ VERSION = "1.4.2"
3
3
  end
@@ -737,5 +737,17 @@ describe 'Client' do
737
737
  index.delete_index
738
738
  end
739
739
  end
740
+
741
+
742
+
743
+ it "should send a custom batch" do
744
+ batch = [
745
+ {:action => "addObject", :indexName => @index.name, :body => { :objectID => "11", :email => "john@be.org" }},
746
+ {:action => "addObject", :indexName => @index.name, :body => { :objectID => "22", :email => "robert@be.org" }}
747
+ ]
748
+ Algolia.batch!(batch)
749
+ res = @index.search("@be.org")
750
+ res["hits"].length.should eq(2)
751
+ end
740
752
  end
741
753
 
metadata CHANGED
@@ -1,83 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algoliasearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.4.1
4
+ version: 1.4.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-04-10 00:00:00.000000000 Z
11
+ date: 2015-05-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: '2.4'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: '2.4'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ">="
31
+ - - '>='
32
32
  - !ruby/object:Gem::Version
33
33
  version: 1.5.1
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ">="
38
+ - - '>='
39
39
  - !ruby/object:Gem::Version
40
40
  version: 1.5.1
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: travis
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ">="
45
+ - - '>='
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - '>='
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rdoc
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ">="
73
+ - - '>='
74
74
  - !ruby/object:Gem::Version
75
75
  version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  description: A simple Ruby client for the algolia.com REST API
@@ -89,8 +89,8 @@ extra_rdoc_files:
89
89
  - LICENSE.txt
90
90
  - README.md
91
91
  files:
92
- - ".rspec"
93
- - ".travis.yml"
92
+ - .rspec
93
+ - .travis.yml
94
94
  - ChangeLog
95
95
  - Gemfile
96
96
  - Gemfile.lock
@@ -121,12 +121,12 @@ require_paths:
121
121
  - lib
122
122
  required_ruby_version: !ruby/object:Gem::Requirement
123
123
  requirements:
124
- - - ">="
124
+ - - '>='
125
125
  - !ruby/object:Gem::Version
126
126
  version: '0'
127
127
  required_rubygems_version: !ruby/object:Gem::Requirement
128
128
  requirements:
129
- - - ">="
129
+ - - '>='
130
130
  - !ruby/object:Gem::Version
131
131
  version: '0'
132
132
  requirements: []