algoliasearch 1.15.1 → 1.16.0

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.
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