algoliasearch 1.15.1 → 1.16.0

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: 83e8b3d9fb893a32b3ba573f94532bdad71aa666
4
- data.tar.gz: 8a5707e5e4f88bb8dde14b13f6c21d4f4c1f67e7
3
+ metadata.gz: bb21e712b8f13f4624b33858edbe573acf33a7d1
4
+ data.tar.gz: 3bb19d2382c63494c56b43266fdf0898da59e9c9
5
5
  SHA512:
6
- metadata.gz: 49a14746f93a764e0f8341f34509825e4533115df3c287b369e68a4cd2296a925c4c928b7bfd95e6c8144ddfb2be1e2825e28c14cace4dad4d096c6879997c7a
7
- data.tar.gz: 3fbc6d92369121be3ed984e14fe925e802c84c11c0fbb1a0a3d281bd242eb46e10f08cb51768ade5fff063bb3e2136e39c52f1f59d5daa2c9828a98f44917296
6
+ metadata.gz: b6324fd4f0dc64f44edf75a8985004cc230de0ad418e114224b90e115f2feec52fa0389328904fa58188ea4e853e2994866cbbb498d479956a50b60f0a91fe69
7
+ data.tar.gz: 894a5a056b54195fa7b71703915ad58159e9f8b717487008d7395f255fd79a7659b36285caa345666fa0811a0d5cac0b4a774be32471f41b11f3293b0f97f98e
data/ChangeLog CHANGED
@@ -1,5 +1,8 @@
1
1
  CHANGELOG
2
2
 
3
+ 2017-09-14 1.16.0
4
+ * New Query Rules API
5
+
3
6
  2017-08-17 1.15.1
4
7
  * Fixed regression introduced in 1.15.0
5
8
 
@@ -175,11 +178,11 @@ CHANGELOG
175
178
  2013-12-16 1.1.15
176
179
 
177
180
  * Embed ca-bundle.crt
178
-
181
+
179
182
  2013-12-11 1.1.14
180
183
 
181
184
  * Added index.add_user_key(acls, validity, rate_limit, maxApiCalls)
182
-
185
+
183
186
  2013-12-10 1.1.13
184
187
 
185
188
  * WebMock integration
data/README.md CHANGED
@@ -19,6 +19,7 @@ You can find the full reference on [Algolia's website](https://www.algolia.com/d
19
19
  ## Table of Contents
20
20
 
21
21
 
22
+
22
23
  1. **[Install](#install)**
23
24
 
24
25
  * [Ruby on Rails](#ruby-on-rails)
@@ -40,6 +41,7 @@ You can find the full reference on [Algolia's website](https://www.algolia.com/d
40
41
 
41
42
  * [index.html](#indexhtml)
42
43
 
44
+ 1. **[List of available methods](#list-of-available-methods)**
43
45
 
44
46
 
45
47
 
@@ -76,6 +78,7 @@ require 'algoliasearch'
76
78
 
77
79
  Algolia.init application_id: 'YourApplicationID',
78
80
  api_key: 'YourAPIKey'
81
+ index = Algolia::Index.new("your_index_name")
79
82
  ```
80
83
 
81
84
  ## Push data
@@ -129,10 +132,10 @@ puts index.search('jimmie paint').to_json
129
132
  ## Search UI
130
133
 
131
134
  **Warning:** If you are building a web application, you may be more interested in using one of our
132
- [frontend search UI librairies](https://www.algolia.com/doc/guides/search-ui/search-libraries/)
135
+ [frontend search UI libraries](https://www.algolia.com/doc/guides/search-ui/search-libraries/)
133
136
 
134
137
  The following example shows how to build a front-end search quickly using
135
- [InstanSearch.js](https://community.algolia.com/instantsearch.js/)
138
+ [InstantSearch.js](https://community.algolia.com/instantsearch.js/)
136
139
 
137
140
  ### index.html
138
141
 
@@ -196,10 +199,97 @@ search.addWidget(
196
199
  search.start();
197
200
  ```
198
201
 
202
+
203
+
204
+
205
+ ## List of available methods
206
+
207
+
208
+
209
+
210
+
211
+ ### Search
212
+
213
+ - [Search an index](https://algolia.com/doc/api-reference/api-methods/search/?language=ruby)
214
+ - [Search for facet values](https://algolia.com/doc/api-reference/api-methods/search-for-facet-values/?language=ruby)
215
+ - [Search multiple indexes](https://algolia.com/doc/api-reference/api-methods/multiple-queries/?language=ruby)
216
+
217
+
218
+
219
+ ### Indexing
220
+
221
+ - [Add objects](https://algolia.com/doc/api-reference/api-methods/add-objects/?language=ruby)
222
+ - [Update objects](https://algolia.com/doc/api-reference/api-methods/update-objects/?language=ruby)
223
+ - [Partial update objects](https://algolia.com/doc/api-reference/api-methods/partial-update-objects/?language=ruby)
224
+ - [Delete objects](https://algolia.com/doc/api-reference/api-methods/delete-objects/?language=ruby)
225
+ - [Delete by query](https://algolia.com/doc/api-reference/api-methods/delete-by-query/?language=ruby)
226
+ - [Get objects](https://algolia.com/doc/api-reference/api-methods/get-objects/?language=ruby)
227
+ - [Wait for operations](https://algolia.com/doc/api-reference/api-methods/wait-task/?language=ruby)
228
+
229
+
230
+
231
+ ### Settings
232
+
233
+ - [Get settings](https://algolia.com/doc/api-reference/api-methods/get-settings/?language=ruby)
234
+ - [Set settings](https://algolia.com/doc/api-reference/api-methods/set-settings/?language=ruby)
235
+
236
+
237
+
238
+ ### Manage indices
239
+
240
+ - [List indexes](https://algolia.com/doc/api-reference/api-methods/list-indices/?language=ruby)
241
+ - [Delete index](https://algolia.com/doc/api-reference/api-methods/delete-index/?language=ruby)
242
+ - [Copy index](https://algolia.com/doc/api-reference/api-methods/copy-index/?language=ruby)
243
+ - [Move index](https://algolia.com/doc/api-reference/api-methods/move-index/?language=ruby)
244
+ - [Clear index](https://algolia.com/doc/api-reference/api-methods/clear-index/?language=ruby)
245
+
246
+
247
+
248
+ ### API Keys
249
+
250
+ - [Create secured API Key](https://algolia.com/doc/api-reference/api-methods/generate-secured-api-key/?language=ruby)
251
+ - [Add API Key](https://algolia.com/doc/api-reference/api-methods/add-api-key/?language=ruby)
252
+ - [Update API Key](https://algolia.com/doc/api-reference/api-methods/update-api-key/?language=ruby)
253
+ - [Delete API Key](https://algolia.com/doc/api-reference/api-methods/delete-api-key/?language=ruby)
254
+ - [Get API Key permissions](https://algolia.com/doc/api-reference/api-methods/get-api-key/?language=ruby)
255
+ - [List API Keys](https://algolia.com/doc/api-reference/api-methods/list-api-keys/?language=ruby)
256
+
257
+
258
+
259
+ ### Synonyms
260
+
261
+ - [Save synonym](https://algolia.com/doc/api-reference/api-methods/save-synonym/?language=ruby)
262
+ - [Batch synonyms](https://algolia.com/doc/api-reference/api-methods/batch-synonyms/?language=ruby)
263
+ - [Delete synonym](https://algolia.com/doc/api-reference/api-methods/delete-synonym/?language=ruby)
264
+ - [Clear all synonyms](https://algolia.com/doc/api-reference/api-methods/clear-synonyms/?language=ruby)
265
+ - [Get synonym](https://algolia.com/doc/api-reference/api-methods/get-synonym/?language=ruby)
266
+ - [Search synonyms](https://algolia.com/doc/api-reference/api-methods/search-synonyms/?language=ruby)
267
+
268
+
269
+
270
+ ### Query rules
271
+
272
+ - [Save a single rule](https://algolia.com/doc/api-reference/api-methods/rules-save/?language=ruby)
273
+ - [Batch save multiple rules](https://algolia.com/doc/api-reference/api-methods/rules-save-batch/?language=ruby)
274
+ - [Read a rule](https://algolia.com/doc/api-reference/api-methods/rules-read/?language=ruby)
275
+ - [Delete a single rule](https://algolia.com/doc/api-reference/api-methods/rules-delete/?language=ruby)
276
+ - [Clear all rules](https://algolia.com/doc/api-reference/api-methods/rules-clear/?language=ruby)
277
+ - [Search for rules](https://algolia.com/doc/api-reference/api-methods/rules-search/?language=ruby)
278
+
279
+
280
+
281
+ ### Advanced
282
+
283
+ - [Custom batch](https://algolia.com/doc/api-reference/api-methods/batch/?language=ruby)
284
+ - [Browse an index](https://algolia.com/doc/api-reference/api-methods/browse/?language=ruby)
285
+ - [Get latest logs](https://algolia.com/doc/api-reference/api-methods/get-logs/?language=ruby)
286
+
287
+
288
+
289
+
199
290
  ## Getting Help
200
291
 
201
292
  - **Need help**? Ask a question to the [Algolia Community](https://discourse.algolia.com/) or on [Stack Overflow](http://stackoverflow.com/questions/tagged/algolia).
202
293
  - **Found a bug?** You can open a [GitHub issue](https://github.com/algolia/algoliasearch-client-ruby/issues).
203
294
 
204
295
 
205
-
data/lib/algolia/index.rb CHANGED
@@ -392,30 +392,34 @@ module Algolia
392
392
 
393
393
  #
394
394
  # Delete all objects matching a query
395
- #
395
+ # This method retrieves all objects synchronously but deletes in batch
396
+ # asynchronously
396
397
  # @param query the query string
397
398
  # @param params the optional query parameters
398
399
  #
399
400
  def delete_by_query(query, params = nil)
400
401
  raise ArgumentError.new('query cannot be nil, use the `clear` method to wipe the entire index') if query.nil? && params.nil?
401
- params ||= {}
402
- params.delete(:hitsPerPage)
403
- params.delete('hitsPerPage')
404
- params.delete(:attributesToRetrieve)
405
- params.delete('attributesToRetrieve')
402
+ params = sanitized_delete_by_query_params(params)
406
403
 
404
+ params[:query] = query
407
405
  params[:hitsPerPage] = 1000
408
406
  params[:distinct] = false
409
407
  params[:attributesToRetrieve] = ['objectID']
410
- last_task = nil
411
- loop do
412
- res = search(query, params)
413
- break if res['hits'].empty?
414
- last_task = delete_objects(res['hits'].map { |h| h['objectID'] })
415
- break if res['hits'].size < 1000
416
- wait_task(last_task['taskID'])
408
+ params[:cursor] = ''
409
+ ids = []
410
+
411
+ while params[:cursor] != nil
412
+ result = browse(params)
413
+
414
+ params[:cursor] = result['cursor']
415
+
416
+ hits = result['hits']
417
+ break if hits.empty?
418
+
419
+ ids += hits.map { |h| h['objectID'] }
417
420
  end
418
- last_task
421
+
422
+ delete_objects(ids)
419
423
  end
420
424
 
421
425
  #
@@ -796,6 +800,106 @@ module Algolia
796
800
  return res
797
801
  end
798
802
 
803
+ # Search rules
804
+ #
805
+ # @param query the query
806
+ # @param params an optional hash of :anchoring, :context, :page, :hitsPerPage
807
+ def search_rules(query, params = {})
808
+ anchoring = params[:anchoring]
809
+ context = params[:context]
810
+ page = params[:page] || params['page'] || 0
811
+ hits_per_page = params[:hitsPerPage] || params['hitsPerPage'] || 20
812
+ params = {
813
+ :query => query,
814
+ :page => page,
815
+ :hitsPerPage => hits_per_page
816
+ }
817
+ params[:anchoring] = anchoring unless anchoring.nil?
818
+ params[:context] = context unless context.nil?
819
+ client.post(Protocol.search_rules_uri(name), params.to_json, :read)
820
+ end
821
+
822
+ # Get a rule
823
+ #
824
+ # @param objectID the rule objectID
825
+ def get_rule(objectID)
826
+ client.get(Protocol.rule_uri(name, objectID), :read)
827
+ end
828
+
829
+ # Delete a rule
830
+ #
831
+ # @param objectID the rule objectID
832
+ # @param forward_to_replicas should we forward the delete to replica indices
833
+ def delete_rule(objectID, forward_to_replicas = false)
834
+ client.delete("#{Protocol.rule_uri(name, objectID)}?forwardToReplicas=#{forward_to_replicas}", :write)
835
+ end
836
+
837
+ # Delete a rule and wait the end of indexing
838
+ #
839
+ # @param objectID the rule objectID
840
+ # @param forward_to_replicas should we forward the delete to replica indices
841
+ def delete_rule!(objectID, forward_to_replicas = false)
842
+ res = delete_rule(objectID, forward_to_replicas)
843
+ wait_task(res["taskID"])
844
+ return res
845
+ end
846
+
847
+ # Save a rule
848
+ #
849
+ # @param objectID the rule objectID
850
+ # @param rule the rule
851
+ # @param forward_to_replicas should we forward the delete to replica indices
852
+ def save_rule(objectID, rule, forward_to_replicas = false)
853
+ client.put("#{Protocol.rule_uri(name, objectID)}?forwardToReplicas=#{forward_to_replicas}", rule.to_json, :write)
854
+ end
855
+
856
+ # Save a rule and wait the end of indexing
857
+ #
858
+ # @param objectID the rule objectID
859
+ # @param rule the rule
860
+ # @param forward_to_replicas should we forward the delete to replica indices
861
+ def save_rule!(objectID, rule, forward_to_replicas = false)
862
+ res = save_rule(objectID, rule, forward_to_replicas)
863
+ wait_task(res["taskID"])
864
+ return res
865
+ end
866
+
867
+ # Clear all rules
868
+ #
869
+ # @param forward_to_replicas should we forward the delete to replica indices
870
+ def clear_rules(forward_to_replicas = false)
871
+ client.post("#{Protocol.clear_rules_uri(name)}?forwardToReplicas=#{forward_to_replicas}")
872
+ end
873
+
874
+ # Clear all rules and wait the end of indexing
875
+ #
876
+ # @param forward_to_replicas should we forward the delete to replica indices
877
+ def clear_rules!(forward_to_replicas = false)
878
+ res = clear_rules(forward_to_replicas)
879
+ wait_task(res["taskID"])
880
+ return res
881
+ end
882
+
883
+ # Add/Update an array of rules
884
+ #
885
+ # @param rules the array of rules to add/update
886
+ # @param forward_to_replicas should we forward the delete to replica indices
887
+ # @param clear_existing_rules should we clear the existing rules before adding the new ones
888
+ def batch_rules(rules, forward_to_replicas = false, clear_existing_rules = false)
889
+ client.post("#{Protocol.batch_rules_uri(name)}?forwardToReplicas=#{forward_to_replicas}&clearExistingRules=#{clear_existing_rules}", rules.to_json, :batch)
890
+ end
891
+
892
+ # Add/Update an array of rules and wait the end of indexing
893
+ #
894
+ # @param rules the array of rules to add/update
895
+ # @param forward_to_replicas should we forward the delete to replica indices
896
+ # @param clear_existing_rules should we clear the existing rules before adding the new ones
897
+ def batch_rules!(rules, forward_to_replicas = false, clear_existing_rules = false)
898
+ res = batch_rules(rules, forward_to_replicas, clear_existing_rules)
899
+ wait_task(res["taskID"])
900
+ return res
901
+ end
902
+
799
903
  # Deprecated
800
904
  alias_method :get_user_key, :get_api_key
801
905
  alias_method :list_user_keys, :list_api_keys
@@ -838,5 +942,13 @@ module Algolia
838
942
  }
839
943
  end
840
944
 
945
+ def sanitized_delete_by_query_params(params)
946
+ params ||= {}
947
+ params.delete(:hitsPerPage)
948
+ params.delete('hitsPerPage')
949
+ params.delete(:attributesToRetrieve)
950
+ params.delete('attributesToRetrieve')
951
+ params
952
+ end
841
953
  end
842
954
  end
@@ -147,5 +147,25 @@ module Algolia
147
147
  "#{synonyms_uri(index)}/batch"
148
148
  end
149
149
 
150
+ def Protocol.rules_uri(index)
151
+ "#{index_uri(index)}/rules"
152
+ end
153
+
154
+ def Protocol.rule_uri(index, object_id)
155
+ "#{rules_uri(index)}/#{CGI.escape(object_id)}"
156
+ end
157
+
158
+ def Protocol.search_rules_uri(index)
159
+ "#{rules_uri(index)}/search"
160
+ end
161
+
162
+ def Protocol.clear_rules_uri(index)
163
+ "#{rules_uri(index)}/clear"
164
+ end
165
+
166
+ def Protocol.batch_rules_uri(index)
167
+ "#{rules_uri(index)}/batch"
168
+ end
169
+
150
170
  end
151
171
  end
@@ -1,3 +1,3 @@
1
1
  module Algolia
2
- VERSION = "1.15.1"
2
+ VERSION = "1.16.0"
3
3
  end
@@ -8,7 +8,7 @@ end
8
8
  # list indexes
9
9
  WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes/).to_return(:body => '{ "items": [] }')
10
10
  # query index
11
- WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "hits": [ { "objectID": 42 } ], "page": 1, "hitsPerPage": 1 }')
11
+ WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "hits": [ { "objectID": 42 } ], "page": 1, "hitsPerPage": 1, "nbHits": 1, "nbPages": 1 }')
12
12
  # delete index
13
13
  WebMock.stub_request(:delete, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+/).to_return(:body => '{ "taskID": 42 }')
14
14
  # clear index
@@ -29,7 +29,7 @@ WebMock.stub_request(:post, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/ba
29
29
  WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{}')
30
30
  WebMock.stub_request(:put, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/settings/).to_return(:body => '{ "taskID": 42 }')
31
31
  # browse
32
- WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/browse/).to_return(:body => '{}')
32
+ WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/browse/).to_return(:body => '{ "hits": [] }')
33
33
  # operations
34
34
  WebMock.stub_request(:post, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/operation/).to_return(:body => '{ "taskID": 42 }')
35
35
  # tasks
@@ -43,4 +43,4 @@ WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/keys/).to_return(:bo
43
43
  WebMock.stub_request(:get, /.*\.algolia(net\.com|\.net)\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
44
44
  WebMock.stub_request(:delete, /.*\.algolia(net\.com|\.net)\/1\/keys\/[^\/]+/).to_return(:body => '{ }')
45
45
  # query POST
46
- WebMock.stub_request(:post, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/query/).to_return(:body => '{ "hits": [ { "objectID": 42 } ], "page": 1, "hitsPerPage": 1 }')
46
+ WebMock.stub_request(:post, /.*\.algolia(net\.com|\.net)\/1\/indexes\/[^\/]+\/query/).to_return(:body => '{ "hits": [ { "objectID": 42 } ], "page": 1, "hitsPerPage": 1, "nbHits": 1, "nbPages": 1 }')
data/spec/client_spec.rb CHANGED
@@ -984,6 +984,37 @@ describe 'Client' do
984
984
  @index.search_synonyms('')['nbHits'].should eq(0)
985
985
  end
986
986
 
987
+ it 'should test Query Rules' do
988
+ rule_1 = {
989
+ :objectID => '42',
990
+ :condition => { :pattern => 'test', :anchoring => 'contains' },
991
+ :consequence => { :params => { :query => 'this is better' } }
992
+ }
993
+ rule_2 = {
994
+ :objectID => '2',
995
+ :condition => { :pattern => 'Pura', :anchoring => 'contains' },
996
+ :consequence => { :params => { :query => 'Pura Vida' } }
997
+ }
998
+
999
+ result = @index.save_rule!(rule_1[:objectID], rule_1)
1000
+ result.should have_key('taskID')
1001
+ result.should have_key('updatedAt')
1002
+
1003
+ @index.get_rule(rule_1[:objectID])['objectID'].should eq(rule_1[:objectID])
1004
+
1005
+ @index.search_rules('better')['nbHits'].should eq(1)
1006
+ @index.search_rules('', { :anchoring => 'contains' })['nbHits'].should eq(1)
1007
+
1008
+ @index.delete_rule!(rule_1[:objectID])
1009
+ @index.search_rules('')['nbHits'].should eq(0)
1010
+
1011
+ @index.batch_rules!([rule_1, rule_2])
1012
+ @index.search_rules('')['nbHits'].should eq(2)
1013
+
1014
+ @index.clear_rules!
1015
+ @index.search_rules('')['nbHits'].should eq(0)
1016
+ end
1017
+
987
1018
  context 'DNS timeout' do
988
1019
  before(:each) do
989
1020
  @client = Algolia::Client.new :application_id => ENV['ALGOLIA_APPLICATION_ID'], :api_key => ENV['ALGOLIA_API_KEY'],
data/spec/mock_spec.rb CHANGED
@@ -16,7 +16,7 @@ describe 'With a mocked client' do
16
16
  it "should add a simple object" do
17
17
  index = Algolia::Index.new("friends")
18
18
  index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
19
- index.search('').should == { "hits" => [ { "objectID" => 42 } ], "page" => 1, "hitsPerPage" => 1 } # mocked
19
+ index.search('').should == { "hits" => [ { "objectID" => 42 } ], "page" => 1, "hitsPerPage" => 1, "nbHits"=>1, "nbPages"=>1 } # mocked
20
20
  index.list_api_keys
21
21
  index.browse
22
22
  index.clear
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: algoliasearch
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.15.1
4
+ version: 1.16.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Algolia
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-08-19 00:00:00.000000000 Z
11
+ date: 2017-09-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: httpclient
@@ -131,7 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
131
131
  version: '0'
132
132
  requirements: []
133
133
  rubyforge_project:
134
- rubygems_version: 2.6.8
134
+ rubygems_version: 2.6.13
135
135
  signing_key:
136
136
  specification_version: 4
137
137
  summary: A simple Ruby client for the algolia.com REST API