algoliasearch 1.23.2 → 1.24.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +6 -0
- data/Gemfile.lock +33 -36
- data/README.md +14 -14
- data/algoliasearch.gemspec +2 -0
- data/lib/algolia/account_client.rb +99 -0
- data/lib/algolia/client.rb +138 -0
- data/lib/algolia/index.rb +116 -0
- data/lib/algolia/version.rb +1 -1
- data/lib/algoliasearch.rb +1 -0
- data/spec/account_client_spec.rb +92 -0
- data/spec/client_spec.rb +114 -0
- data/spec/spec_helper.rb +9 -0
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6656588b81231ae7bff38c4b5fc55bb36194233505bc493107dd3dd9526ae86d
|
4
|
+
data.tar.gz: c64bf649901a0ea9f5ac1997b55f9917cc719bf59a956ea0db7b751268838700
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c19eb997c9a08b5e1219296756d99c61f9d22af53d06c9589537418d94755e030def9ebebbf8357670b081e1229d77cc674c795fa33c953bb7dc6dde6d3f26c6
|
7
|
+
data.tar.gz: 025ba93db32d9d3b6aa478dd638207ad84ec97df681c5807dbfc858ff88a8e2e77ef637e7eaa2b02738d6b47859c5b923cf02d3a74afa1b917062e7b8ba757cd
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,9 @@
|
|
1
|
+
## [1.24.0](https://github.com/algolia/algoliasearch-client-ruby/releases/tag/1.24.0) (2018-11-28)
|
2
|
+
|
3
|
+
* Feat(adds-account-client-copy-index): adds `copy_index` to account client ([#324](https://github.com/algolia/algoliasearch-client-ruby/pull/324))
|
4
|
+
* Feat(replace-all-methods): adds `replace_all_rules`, `replace_all_objects` and `replace_all_synonyms` to search index ([#323](https://github.com/algolia/algoliasearch-client-ruby/pull/323))
|
5
|
+
* Feat(scoped-copy-methods): adds `copy_settings`, `copy_synonyms` and `copy_rules` to search client ([#322](https://github.com/algolia/algoliasearch-client-ruby/pull/322))
|
6
|
+
|
1
7
|
## [1.23.2](https://github.com/algolia/algoliasearch-client-ruby/releases/tag/1.23.2) (2018-06-19)
|
2
8
|
|
3
9
|
* Fix(analytics): gem without new analytics class (#306)
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
algoliasearch (1.23.
|
4
|
+
algoliasearch (1.23.2)
|
5
5
|
httpclient (~> 2.8, >= 2.8.3)
|
6
6
|
json (>= 1.5.1)
|
7
7
|
|
@@ -9,24 +9,24 @@ GEM
|
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
11
|
addressable (2.4.0)
|
12
|
-
backports (3.11.
|
13
|
-
coveralls (0.
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
backports (3.11.4)
|
13
|
+
coveralls (0.8.22)
|
14
|
+
json (>= 1.8, < 3)
|
15
|
+
simplecov (~> 0.16.1)
|
16
|
+
term-ansicolor (~> 1.3)
|
17
|
+
thor (~> 0.19.4)
|
18
|
+
tins (~> 1.6)
|
19
19
|
crack (0.4.3)
|
20
20
|
safe_yaml (~> 1.0.0)
|
21
21
|
diff-lcs (1.3)
|
22
|
-
docile (1.3.
|
22
|
+
docile (1.3.1)
|
23
23
|
ethon (0.11.0)
|
24
24
|
ffi (>= 1.3.0)
|
25
|
-
faraday (0.
|
25
|
+
faraday (0.15.3)
|
26
26
|
multipart-post (>= 1.2, < 3)
|
27
27
|
faraday_middleware (0.12.2)
|
28
28
|
faraday (>= 0.7.4, < 1.0)
|
29
|
-
ffi (1.9.
|
29
|
+
ffi (1.9.25)
|
30
30
|
ffi2-generators (0.1.1)
|
31
31
|
gh (0.15.1)
|
32
32
|
addressable (~> 2.4.0)
|
@@ -36,12 +36,11 @@ GEM
|
|
36
36
|
net-http-persistent (~> 2.9)
|
37
37
|
net-http-pipeline
|
38
38
|
hashdiff (0.3.7)
|
39
|
-
highline (1.
|
39
|
+
highline (1.7.10)
|
40
40
|
httpclient (2.8.3)
|
41
41
|
json (2.1.0)
|
42
42
|
launchy (2.4.3)
|
43
43
|
addressable (~> 2.3)
|
44
|
-
mime-types (1.25.1)
|
45
44
|
multi_json (1.13.1)
|
46
45
|
multipart-post (2.0.0)
|
47
46
|
net-http-persistent (2.9.4)
|
@@ -50,22 +49,20 @@ GEM
|
|
50
49
|
json
|
51
50
|
websocket (~> 1.0)
|
52
51
|
rake (12.3.1)
|
53
|
-
rdoc (6.0.
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
rspec-
|
58
|
-
|
59
|
-
rspec-
|
60
|
-
rspec-
|
61
|
-
rspec-support (~> 3.7.0)
|
62
|
-
rspec-expectations (3.7.0)
|
52
|
+
rdoc (6.0.4)
|
53
|
+
rspec (3.8.0)
|
54
|
+
rspec-core (~> 3.8.0)
|
55
|
+
rspec-expectations (~> 3.8.0)
|
56
|
+
rspec-mocks (~> 3.8.0)
|
57
|
+
rspec-core (3.8.0)
|
58
|
+
rspec-support (~> 3.8.0)
|
59
|
+
rspec-expectations (3.8.2)
|
63
60
|
diff-lcs (>= 1.2.0, < 2.0)
|
64
|
-
rspec-support (~> 3.
|
65
|
-
rspec-mocks (3.
|
61
|
+
rspec-support (~> 3.8.0)
|
62
|
+
rspec-mocks (3.8.0)
|
66
63
|
diff-lcs (>= 1.2.0, < 2.0)
|
67
|
-
rspec-support (~> 3.
|
68
|
-
rspec-support (3.
|
64
|
+
rspec-support (~> 3.8.0)
|
65
|
+
rspec-support (3.8.0)
|
69
66
|
rubysl (2.2.0)
|
70
67
|
rubysl-abbrev (~> 2.0)
|
71
68
|
rubysl-base64 (~> 2.0)
|
@@ -246,7 +243,7 @@ GEM
|
|
246
243
|
rubysl-singleton (2.0.0)
|
247
244
|
rubysl-socket (2.2.1)
|
248
245
|
rubysl-fcntl (~> 2.0)
|
249
|
-
rubysl-stringio (2.
|
246
|
+
rubysl-stringio (2.3)
|
250
247
|
rubysl-strscan (2.0.0)
|
251
248
|
rubysl-sync (2.0.0)
|
252
249
|
rubysl-syslog (2.1.0)
|
@@ -274,11 +271,11 @@ GEM
|
|
274
271
|
json (>= 1.8, < 3)
|
275
272
|
simplecov-html (~> 0.10.0)
|
276
273
|
simplecov-html (0.10.2)
|
277
|
-
term-ansicolor (1.
|
278
|
-
tins (~> 0
|
279
|
-
thor (0.
|
280
|
-
tins (
|
281
|
-
travis (1.8.
|
274
|
+
term-ansicolor (1.7.0)
|
275
|
+
tins (~> 1.0)
|
276
|
+
thor (0.19.4)
|
277
|
+
tins (1.20.2)
|
278
|
+
travis (1.8.9)
|
282
279
|
backports
|
283
280
|
faraday (~> 0.9)
|
284
281
|
faraday_middleware (~> 0.9, >= 0.9.1)
|
@@ -289,11 +286,11 @@ GEM
|
|
289
286
|
typhoeus (~> 0.6, >= 0.6.8)
|
290
287
|
typhoeus (0.8.0)
|
291
288
|
ethon (>= 0.8.0)
|
292
|
-
webmock (3.
|
289
|
+
webmock (3.4.2)
|
293
290
|
addressable (>= 2.3.6)
|
294
291
|
crack (>= 0.3.2)
|
295
292
|
hashdiff
|
296
|
-
websocket (1.2.
|
293
|
+
websocket (1.2.8)
|
297
294
|
|
298
295
|
PLATFORMS
|
299
296
|
ruby
|
@@ -310,4 +307,4 @@ DEPENDENCIES
|
|
310
307
|
webmock
|
311
308
|
|
312
309
|
BUNDLED WITH
|
313
|
-
1.
|
310
|
+
1.17.1
|
data/README.md
CHANGED
@@ -173,7 +173,7 @@ var search = instantsearch({
|
|
173
173
|
appId: 'YourApplicationID',
|
174
174
|
apiKey: 'YourSearchOnlyAPIKey', // search only API key, no ADMIN key
|
175
175
|
indexName: 'contacts',
|
176
|
-
|
176
|
+
routing: true,
|
177
177
|
searchParameters: {
|
178
178
|
hitsPerPage: 10
|
179
179
|
}
|
@@ -209,10 +209,10 @@ search.start();
|
|
209
209
|
|
210
210
|
### Search
|
211
211
|
|
212
|
-
- [Search
|
212
|
+
- [Search index](https://algolia.com/doc/api-reference/api-methods/search/?language=ruby)
|
213
213
|
- [Search for facet values](https://algolia.com/doc/api-reference/api-methods/search-for-facet-values/?language=ruby)
|
214
214
|
- [Search multiple indexes](https://algolia.com/doc/api-reference/api-methods/multiple-queries/?language=ruby)
|
215
|
-
- [Browse
|
215
|
+
- [Browse index](https://algolia.com/doc/api-reference/api-methods/browse/?language=ruby)
|
216
216
|
|
217
217
|
|
218
218
|
|
@@ -276,12 +276,12 @@ search.start();
|
|
276
276
|
|
277
277
|
### Query rules
|
278
278
|
|
279
|
-
- [Save
|
280
|
-
- [Batch
|
281
|
-
- [Get
|
282
|
-
- [Delete
|
283
|
-
- [Clear
|
284
|
-
- [Search
|
279
|
+
- [Save rule](https://algolia.com/doc/api-reference/api-methods/rules-save/?language=ruby)
|
280
|
+
- [Batch rules](https://algolia.com/doc/api-reference/api-methods/rules-save-batch/?language=ruby)
|
281
|
+
- [Get rule](https://algolia.com/doc/api-reference/api-methods/rules-get/?language=ruby)
|
282
|
+
- [Delete rule](https://algolia.com/doc/api-reference/api-methods/rules-delete/?language=ruby)
|
283
|
+
- [Clear rules](https://algolia.com/doc/api-reference/api-methods/rules-clear/?language=ruby)
|
284
|
+
- [Search rules](https://algolia.com/doc/api-reference/api-methods/rules-search/?language=ruby)
|
285
285
|
- [Export rules](https://algolia.com/doc/api-reference/api-methods/rules-export/?language=ruby)
|
286
286
|
|
287
287
|
|
@@ -289,11 +289,11 @@ search.start();
|
|
289
289
|
|
290
290
|
### A/B Test
|
291
291
|
|
292
|
-
- [Add
|
293
|
-
- [Get
|
294
|
-
- [List A/B tests](https://algolia.com/doc/api-reference/api-methods/
|
295
|
-
- [Stop
|
296
|
-
- [Delete
|
292
|
+
- [Add A/B test](https://algolia.com/doc/api-reference/api-methods/add-ab-test/?language=ruby)
|
293
|
+
- [Get A/B test](https://algolia.com/doc/api-reference/api-methods/get-ab-test/?language=ruby)
|
294
|
+
- [List A/B tests](https://algolia.com/doc/api-reference/api-methods/list-ab-tests/?language=ruby)
|
295
|
+
- [Stop A/B test](https://algolia.com/doc/api-reference/api-methods/stop-ab-test/?language=ruby)
|
296
|
+
- [Delete A/B test](https://algolia.com/doc/api-reference/api-methods/delete-ab-test/?language=ruby)
|
297
297
|
|
298
298
|
|
299
299
|
|
data/algoliasearch.gemspec
CHANGED
@@ -43,6 +43,7 @@ Gem::Specification.new do |s|
|
|
43
43
|
"algoliasearch.gemspec",
|
44
44
|
"contacts.json",
|
45
45
|
"lib/algolia/analytics.rb",
|
46
|
+
"lib/algolia/account_client.rb",
|
46
47
|
"lib/algolia/client.rb",
|
47
48
|
"lib/algolia/error.rb",
|
48
49
|
"lib/algolia/index.rb",
|
@@ -51,6 +52,7 @@ Gem::Specification.new do |s|
|
|
51
52
|
"lib/algolia/webmock.rb",
|
52
53
|
"lib/algoliasearch.rb",
|
53
54
|
"resources/ca-bundle.crt",
|
55
|
+
"spec/account_client_spec.rb",
|
54
56
|
"spec/client_spec.rb",
|
55
57
|
"spec/mock_spec.rb",
|
56
58
|
"spec/spec_helper.rb",
|
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'algolia/error'
|
2
|
+
|
3
|
+
module Algolia
|
4
|
+
#
|
5
|
+
# A class which encapsulates the HTTPS communication with the Algolia
|
6
|
+
# API server for cross-app operations.
|
7
|
+
#
|
8
|
+
class AccountClient
|
9
|
+
class << self
|
10
|
+
#
|
11
|
+
# Copies settings, synonyms, rules and objects from the source index to the
|
12
|
+
# destination index. The replicas of the source index should not be copied.
|
13
|
+
#
|
14
|
+
# Throw an exception if the destination index already exists
|
15
|
+
# Throw an exception if the indices are on the same application
|
16
|
+
#
|
17
|
+
# @param source_index the source index object
|
18
|
+
# @param destination_index the destination index object
|
19
|
+
# @param request_options contains extra parameters to send with your query
|
20
|
+
#
|
21
|
+
def copy_index(source_index, destination_index, request_options = {})
|
22
|
+
raise AlgoliaError.new('The indexes are in the same application. Use Algolia::Client.copy_index instead.') if source_index.client.application_id == destination_index.client.application_id
|
23
|
+
|
24
|
+
begin
|
25
|
+
settings = destination_index.get_settings()
|
26
|
+
rescue AlgoliaError
|
27
|
+
# Destination index does not exists. We can proceed.
|
28
|
+
else
|
29
|
+
raise AlgoliaError.new("Destination index already exists. Please delete it before copying index across applications.")
|
30
|
+
end
|
31
|
+
|
32
|
+
responses = []
|
33
|
+
|
34
|
+
settings = source_index.get_settings()
|
35
|
+
responses << destination_index.set_settings(settings, {}, request_options)
|
36
|
+
|
37
|
+
synonyms = []
|
38
|
+
source_index.export_synonyms(100, request_options) do |synonym|
|
39
|
+
synonym.delete('_highlightResult')
|
40
|
+
synonyms << synonym
|
41
|
+
end
|
42
|
+
|
43
|
+
responses << destination_index.batch_synonyms(synonyms, false, false, request_options)
|
44
|
+
|
45
|
+
rules = []
|
46
|
+
source_index.export_rules(100, request_options) do |rule|
|
47
|
+
rule.delete('_highlightResult')
|
48
|
+
rules << rule
|
49
|
+
end
|
50
|
+
responses << destination_index.batch_rules(rules, false, false, request_options)
|
51
|
+
|
52
|
+
# Copy objects
|
53
|
+
responses = []
|
54
|
+
batch = []
|
55
|
+
batch_size = 1000
|
56
|
+
count = 0
|
57
|
+
|
58
|
+
source_index.browse()['hits'].each do |obj|
|
59
|
+
batch << obj
|
60
|
+
count += 1
|
61
|
+
|
62
|
+
if count == batch_size
|
63
|
+
responses << destination_index.save_objects(batch, request_options)
|
64
|
+
batch = []
|
65
|
+
count = 0
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
if batch.any?
|
70
|
+
responses << destination_index.save_objects(batch, request_options)
|
71
|
+
end
|
72
|
+
|
73
|
+
responses
|
74
|
+
end
|
75
|
+
|
76
|
+
#
|
77
|
+
# The method copy settings, synonyms, rules and objects from the source index
|
78
|
+
# to the destination index and wait end of indexing. The replicas of the
|
79
|
+
# source index should not be copied
|
80
|
+
#
|
81
|
+
# Throw an exception if the destination index already exists
|
82
|
+
# Throw an exception if the indices are on the same application
|
83
|
+
#
|
84
|
+
# @param source_index the source index object
|
85
|
+
# @param destination_index the destination index object
|
86
|
+
# @param request_options contains extra parameters to send with your query
|
87
|
+
#
|
88
|
+
def copy_index!(source_index, destination_index, request_options = {})
|
89
|
+
responses = self.copy_index(source_index, destination_index, request_options)
|
90
|
+
|
91
|
+
responses.each do |res|
|
92
|
+
destination_index.wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
93
|
+
end
|
94
|
+
|
95
|
+
responses
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
data/lib/algolia/client.rb
CHANGED
@@ -208,6 +208,78 @@ module Algolia
|
|
208
208
|
res
|
209
209
|
end
|
210
210
|
|
211
|
+
#
|
212
|
+
# Copy an existing index settings.
|
213
|
+
#
|
214
|
+
# @param src_index the name of index to copy.
|
215
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName's settings (destination's settings will be overriten if it already exist).
|
216
|
+
# @param request_options contains extra parameters to send with your query
|
217
|
+
#
|
218
|
+
def copy_settings(src_index, dst_index, request_options = {})
|
219
|
+
copy_index(src_index, dst_index, ['settings'], request_options)
|
220
|
+
end
|
221
|
+
|
222
|
+
#
|
223
|
+
# Copy an existing index settings and wait until the copy has been processed.
|
224
|
+
#
|
225
|
+
# @param src_index the name of index to copy.
|
226
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName settings (destination settings will be overriten if it already exist).
|
227
|
+
# @param request_options contains extra parameters to send with your query
|
228
|
+
#
|
229
|
+
def copy_settings!(src_index, dst_index, request_options = {})
|
230
|
+
res = copy_settings(src_index, dst_index, request_options)
|
231
|
+
wait_task(dst_index, res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
232
|
+
res
|
233
|
+
end
|
234
|
+
|
235
|
+
#
|
236
|
+
# Copy an existing index synonyms.
|
237
|
+
#
|
238
|
+
# @param src_index the name of index to copy.
|
239
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName's synonyms (destination's synonyms will be overriten if it already exist).
|
240
|
+
# @param request_options contains extra parameters to send with your query
|
241
|
+
#
|
242
|
+
def copy_synonyms(src_index, dst_index, request_options = {})
|
243
|
+
copy_index(src_index, dst_index, ['synonyms'], request_options)
|
244
|
+
end
|
245
|
+
|
246
|
+
#
|
247
|
+
# Copy an existing index synonyms and wait until the copy has been processed.
|
248
|
+
#
|
249
|
+
# @param src_index the name of index to copy.
|
250
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName synonyms (destination synonyms will be overriten if it already exist).
|
251
|
+
# @param request_options contains extra parameters to send with your query
|
252
|
+
#
|
253
|
+
def copy_synonyms!(src_index, dst_index, request_options = {})
|
254
|
+
res = copy_synonyms(src_index, dst_index, request_options)
|
255
|
+
wait_task(dst_index, res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
256
|
+
res
|
257
|
+
end
|
258
|
+
|
259
|
+
#
|
260
|
+
# Copy an existing index rules.
|
261
|
+
#
|
262
|
+
# @param src_index the name of index to copy.
|
263
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName's rules (destination's rules will be overriten if it already exist).
|
264
|
+
# @param request_options contains extra parameters to send with your query
|
265
|
+
#
|
266
|
+
def copy_rules(src_index, dst_index, request_options = {})
|
267
|
+
copy_index(src_index, dst_index, ['rules'], request_options)
|
268
|
+
end
|
269
|
+
|
270
|
+
#
|
271
|
+
# Copy an existing index rules and wait until the copy has been processed.
|
272
|
+
#
|
273
|
+
# @param src_index the name of index to copy.
|
274
|
+
# @param dst_index the new index name that will contains a copy of srcIndexName rules (destination rules will be overriten if it already exist).
|
275
|
+
# @param request_options contains extra parameters to send with your query
|
276
|
+
#
|
277
|
+
def copy_rules!(src_index, dst_index, request_options = {})
|
278
|
+
res = copy_rules(src_index, dst_index, request_options)
|
279
|
+
wait_task(dst_index, res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
280
|
+
res
|
281
|
+
end
|
282
|
+
|
211
283
|
#
|
212
284
|
# Delete an index
|
213
285
|
# @param name the name of the index to delete
|
@@ -740,6 +812,72 @@ module Algolia
|
|
740
812
|
Algolia.client.copy_index!(src_index, dst_index, scope, request_options)
|
741
813
|
end
|
742
814
|
|
815
|
+
#
|
816
|
+
# Copy an existing index settings.
|
817
|
+
#
|
818
|
+
# @param src_index the name of index to copy.
|
819
|
+
# @param dst_index the new index name that will contains a copy of src_index_name settings (destination settings will be overriten if it already exist).
|
820
|
+
# @param request_options contains extra parameters to send with your query
|
821
|
+
#
|
822
|
+
def Algolia.copy_settings(src_index, dst_index, request_options = {})
|
823
|
+
Algolia.client.copy_settings(src_index, dst_index, request_options)
|
824
|
+
end
|
825
|
+
|
826
|
+
#
|
827
|
+
# Copy an existing index settings and wait until the copy has been processed.
|
828
|
+
#
|
829
|
+
# @param src_index the name of index to copy.
|
830
|
+
# @param dst_index the new index name that will contains a copy of src_index_name settings (destination settings will be overriten if it already exist).
|
831
|
+
# @param request_options contains extra parameters to send with your query
|
832
|
+
#
|
833
|
+
def Algolia.copy_settings!(src_index, dst_index, request_options = {})
|
834
|
+
Algolia.client.copy_settings!(src_index, dst_index, request_options)
|
835
|
+
end
|
836
|
+
|
837
|
+
#
|
838
|
+
# Copy an existing index synonyms.
|
839
|
+
#
|
840
|
+
# @param src_index the name of index to copy.
|
841
|
+
# @param dst_index the new index name that will contains a copy of src_index_name synonyms (destination synonyms will be overriten if it already exist).
|
842
|
+
# @param request_options contains extra parameters to send with your query
|
843
|
+
#
|
844
|
+
def Algolia.copy_synonyms(src_index, dst_index, request_options = {})
|
845
|
+
Algolia.client.copy_synonyms(src_index, dst_index, request_options)
|
846
|
+
end
|
847
|
+
|
848
|
+
#
|
849
|
+
# Copy an existing index synonyms and wait until the copy has been processed.
|
850
|
+
#
|
851
|
+
# @param src_index the name of index to copy.
|
852
|
+
# @param dst_index the new index name that will contains a copy of src_index_name synonyms (destination synonyms will be overriten if it already exist).
|
853
|
+
# @param request_options contains extra parameters to send with your query
|
854
|
+
#
|
855
|
+
def Algolia.copy_synonyms!(src_index, dst_index, request_options = {})
|
856
|
+
Algolia.client.copy_synonyms!(src_index, dst_index, request_options)
|
857
|
+
end
|
858
|
+
|
859
|
+
#
|
860
|
+
# Copy an existing index rules.
|
861
|
+
#
|
862
|
+
# @param src_index the name of index to copy.
|
863
|
+
# @param dst_index the new index name that will contains a copy of src_index_name rules (destination rules will be overriten if it already exist).
|
864
|
+
# @param request_options contains extra parameters to send with your query
|
865
|
+
#
|
866
|
+
def Algolia.copy_rules(src_index, dst_index, request_options = {})
|
867
|
+
Algolia.client.copy_rules(src_index, dst_index, request_options)
|
868
|
+
end
|
869
|
+
|
870
|
+
#
|
871
|
+
# Copy an existing index rules and wait until the copy has been processed.
|
872
|
+
#
|
873
|
+
# @param src_index the name of index to copy.
|
874
|
+
# @param dst_index the new index name that will contains a copy of src_index_name rules (destination rules will be overriten if it already exist).
|
875
|
+
# @param request_options contains extra parameters to send with your query
|
876
|
+
#
|
877
|
+
def Algolia.copy_rules!(src_index, dst_index, request_options = {})
|
878
|
+
Algolia.client.copy_rules!(src_index, dst_index, request_options)
|
879
|
+
end
|
880
|
+
|
743
881
|
#
|
744
882
|
# Delete an index
|
745
883
|
#
|
data/lib/algolia/index.rb
CHANGED
@@ -333,6 +333,76 @@ module Algolia
|
|
333
333
|
res
|
334
334
|
end
|
335
335
|
|
336
|
+
#
|
337
|
+
# Override the current objects by the given array of objects and wait end of indexing. Settings,
|
338
|
+
# synonyms and query rules are untouched. The objects are replaced without any downtime.
|
339
|
+
#
|
340
|
+
# @param objects the array of objects to save
|
341
|
+
# @param request_options contains extra parameters to send with your query
|
342
|
+
#
|
343
|
+
def replace_all_objects(objects, request_options = {})
|
344
|
+
safe = request_options[:safe] || request_options['safe'] || false
|
345
|
+
request_options.delete(:safe)
|
346
|
+
request_options.delete('safe')
|
347
|
+
|
348
|
+
tmp_index = @client.init_index(@name + '_tmp_' + rand(10000000).to_s)
|
349
|
+
|
350
|
+
responses = []
|
351
|
+
|
352
|
+
scope = ['settings', 'synonyms', 'rules']
|
353
|
+
res = @client.copy_index(@name, tmp_index.name, scope, request_options)
|
354
|
+
responses << res
|
355
|
+
|
356
|
+
if safe
|
357
|
+
wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
358
|
+
end
|
359
|
+
|
360
|
+
batch = []
|
361
|
+
batch_size = 1000
|
362
|
+
count = 0
|
363
|
+
|
364
|
+
objects.each do |object|
|
365
|
+
batch << object
|
366
|
+
count += 1
|
367
|
+
if count == batch_size
|
368
|
+
res = tmp_index.add_objects(batch, request_options)
|
369
|
+
responses << res
|
370
|
+
batch = []
|
371
|
+
count = 0
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
if batch.any?
|
376
|
+
res = tmp_index.add_objects(batch, request_options)
|
377
|
+
responses << res
|
378
|
+
end
|
379
|
+
|
380
|
+
if safe
|
381
|
+
responses.each do |res|
|
382
|
+
tmp_index.wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
383
|
+
end
|
384
|
+
end
|
385
|
+
|
386
|
+
res = @client.move_index(tmp_index.name, @name, request_options)
|
387
|
+
responses << res
|
388
|
+
|
389
|
+
if safe
|
390
|
+
wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
391
|
+
end
|
392
|
+
|
393
|
+
responses
|
394
|
+
end
|
395
|
+
|
396
|
+
#
|
397
|
+
# Override the current objects by the given array of objects and wait end of indexing
|
398
|
+
#
|
399
|
+
# @param objects the array of objects to save
|
400
|
+
# @param request_options contains extra parameters to send with your query
|
401
|
+
#
|
402
|
+
def replace_all_objects!(objects, request_options = {})
|
403
|
+
replace_all_objects(objects, request_options.merge(:safe => true))
|
404
|
+
end
|
405
|
+
|
336
406
|
#
|
337
407
|
# Update partially an object (only update attributes passed in argument)
|
338
408
|
#
|
@@ -915,6 +985,29 @@ module Algolia
|
|
915
985
|
res
|
916
986
|
end
|
917
987
|
|
988
|
+
#
|
989
|
+
# Replace synonyms in the index by the given array of synonyms
|
990
|
+
#
|
991
|
+
# @param synonyms the array of synonyms to add
|
992
|
+
# @param request_options contains extra parameters to send with your query
|
993
|
+
#
|
994
|
+
def replace_all_synonyms(synonyms, request_options = {})
|
995
|
+
forward_to_replicas = request_options[:forwardToReplicas] || request_options['forwardToReplicas'] || false
|
996
|
+
batch_synonyms(synonyms, forward_to_replicas, true, request_options)
|
997
|
+
end
|
998
|
+
|
999
|
+
#
|
1000
|
+
# Replace synonyms in the index by the given array of synonyms and wait the end of indexing
|
1001
|
+
#
|
1002
|
+
# @param synonyms the array of synonyms to add
|
1003
|
+
# @param request_options contains extra parameters to send with your query
|
1004
|
+
#
|
1005
|
+
def replace_all_synonyms!(synonyms, request_options = {})
|
1006
|
+
res = replace_all_synonyms(synonyms, request_options)
|
1007
|
+
wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
1008
|
+
res
|
1009
|
+
end
|
1010
|
+
|
918
1011
|
#
|
919
1012
|
# Export the full list of synonyms
|
920
1013
|
# Accepts an optional block to which it will pass each synonym
|
@@ -1069,6 +1162,29 @@ module Algolia
|
|
1069
1162
|
return res
|
1070
1163
|
end
|
1071
1164
|
|
1165
|
+
#
|
1166
|
+
# Replace rules in the index by the given array of rules
|
1167
|
+
#
|
1168
|
+
# @param rules the array of rules to add
|
1169
|
+
# @param request_options contains extra parameters to send with your query
|
1170
|
+
#
|
1171
|
+
def replace_all_rules(rules, request_options = {})
|
1172
|
+
forward_to_replicas = request_options[:forwardToReplicas] || request_options['forwardToReplicas'] || false
|
1173
|
+
batch_rules(rules, forward_to_replicas, true, request_options)
|
1174
|
+
end
|
1175
|
+
|
1176
|
+
#
|
1177
|
+
# Replace rules in the index by the given array of rules and wait the end of indexing
|
1178
|
+
#
|
1179
|
+
# @param rules the array of rules to add
|
1180
|
+
# @param request_options contains extra parameters to send with your query
|
1181
|
+
#
|
1182
|
+
def replace_all_rules!(rules, request_options = {})
|
1183
|
+
res = replace_all_rules(rules, request_options)
|
1184
|
+
wait_task(res['taskID'], WAIT_TASK_DEFAULT_TIME_BEFORE_RETRY, request_options)
|
1185
|
+
res
|
1186
|
+
end
|
1187
|
+
|
1072
1188
|
#
|
1073
1189
|
# Export the full list of rules
|
1074
1190
|
# Accepts an optional block to which it will pass each rule
|
data/lib/algolia/version.rb
CHANGED
data/lib/algoliasearch.rb
CHANGED
@@ -0,0 +1,92 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
3
|
+
require 'securerandom'
|
4
|
+
|
5
|
+
describe 'Account client' do
|
6
|
+
before(:all) do
|
7
|
+
client_1 = Algolia::Client.new({
|
8
|
+
:application_id => ENV['ALGOLIA_APPLICATION_ID_1'],
|
9
|
+
:api_key => ENV['ALGOLIA_ADMIN_KEY_1']
|
10
|
+
})
|
11
|
+
|
12
|
+
@index_1 = client_1.init_index(index_name('account_client_1'))
|
13
|
+
|
14
|
+
client_2 = Algolia::Client.new({
|
15
|
+
:application_id => ENV['ALGOLIA_APPLICATION_ID_1'],
|
16
|
+
:api_key => ENV['ALGOLIA_ADMIN_KEY_1']
|
17
|
+
})
|
18
|
+
|
19
|
+
@index_2 = client_2.init_index(index_name('account_client_2'))
|
20
|
+
|
21
|
+
client_3 = Algolia::Client.new({
|
22
|
+
:application_id => ENV['ALGOLIA_APPLICATION_ID_2'],
|
23
|
+
:api_key => ENV['ALGOLIA_ADMIN_KEY_2']
|
24
|
+
})
|
25
|
+
|
26
|
+
@index_3 = client_3.init_index(index_name('account_client_3'))
|
27
|
+
|
28
|
+
@index_1.delete_index rescue 'not fatal'
|
29
|
+
@index_2.delete_index rescue 'not fatal'
|
30
|
+
@index_3.delete_index rescue 'not fatal'
|
31
|
+
end
|
32
|
+
|
33
|
+
after(:all) do
|
34
|
+
@index_1.delete_index rescue 'not fatal'
|
35
|
+
@index_2.delete_index rescue 'not fatal'
|
36
|
+
@index_3.delete_index rescue 'not fatal'
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should not allow operations in the same application' do
|
40
|
+
expect {
|
41
|
+
Algolia::AccountClient.copy_index!(@index_1, @index_2)
|
42
|
+
}.to raise_exception(
|
43
|
+
Algolia::AlgoliaError,
|
44
|
+
'The indexes are in the same application. Use Algolia::Client.copy_index instead.'
|
45
|
+
)
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'should perform a cross app copy index and assert that destination must not exist' do
|
49
|
+
|
50
|
+
@index_1.save_objects! ([
|
51
|
+
{:objectID => 'one'},
|
52
|
+
])
|
53
|
+
|
54
|
+
@index_1.batch_rules! ([
|
55
|
+
{
|
56
|
+
:objectID => 'one',
|
57
|
+
:condition => {:pattern => 'test', :anchoring => 'contains'},
|
58
|
+
:consequence => {:params => {:query => 'this is better'}}
|
59
|
+
}
|
60
|
+
])
|
61
|
+
|
62
|
+
@index_1.batch_synonyms! ([
|
63
|
+
{:objectID => 'one', :type => 'synonym', :synonyms => ['San Francisco', 'SF']}
|
64
|
+
])
|
65
|
+
|
66
|
+
@index_1.set_settings! ({:searchableAttributes => ['objectID']})
|
67
|
+
|
68
|
+
Algolia::AccountClient.copy_index!(@index_1, @index_3)
|
69
|
+
|
70
|
+
res = @index_3.search('');
|
71
|
+
res['nbHits'].should eq(1)
|
72
|
+
res['hits'][0]['objectID'].should eq('one')
|
73
|
+
|
74
|
+
res = @index_3.search_rules('')['hits']
|
75
|
+
res.size.should eq(1)
|
76
|
+
res[0]['objectID'].should eq('one')
|
77
|
+
|
78
|
+
res = @index_3.search_synonyms('')['hits']
|
79
|
+
res.size.should eq(1)
|
80
|
+
res[0]['objectID'].should eq('one')
|
81
|
+
|
82
|
+
@index_3.get_settings['searchableAttributes'].should eq(['objectID'])
|
83
|
+
|
84
|
+
expect {
|
85
|
+
Algolia::AccountClient.copy_index!(@index_1, @index_3)
|
86
|
+
}.to raise_exception(
|
87
|
+
Algolia::AlgoliaError,
|
88
|
+
'Destination index already exists. Please delete it before copying index across applications.'
|
89
|
+
)
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
data/spec/client_spec.rb
CHANGED
@@ -249,6 +249,17 @@ describe 'Client' do
|
|
249
249
|
res["hits"].length.should eq(2)
|
250
250
|
end
|
251
251
|
|
252
|
+
it "should replace all objects" do
|
253
|
+
@index.save_objects!([{:objectID => '1'}, {:objectID => '2'}])
|
254
|
+
@index.replace_all_objects!([{'color' => 'black'}, {:objectID => '4', 'color' => 'green'}])
|
255
|
+
|
256
|
+
res = @index.search('')
|
257
|
+
res["hits"].length.should eq(2)
|
258
|
+
res = @index.search('black')
|
259
|
+
res["hits"][0]['color'].should eq('black')
|
260
|
+
@index.get_object('4')['color'].should eq('green')
|
261
|
+
end
|
262
|
+
|
252
263
|
it "should throw an exception if invalid argument" do
|
253
264
|
expect { @index.add_object!([ {:name => "test"} ]) }.to raise_error(ArgumentError)
|
254
265
|
expect { @index.add_objects!([ [ {:name => "test"} ] ]) }.to raise_error(ArgumentError)
|
@@ -262,6 +273,10 @@ describe 'Client' do
|
|
262
273
|
end
|
263
274
|
|
264
275
|
it "should be thread safe" do
|
276
|
+
@index.clear!
|
277
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
|
278
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
|
279
|
+
|
265
280
|
threads = []
|
266
281
|
64.times do
|
267
282
|
t = Thread.new do
|
@@ -430,6 +445,66 @@ describe 'Client' do
|
|
430
445
|
index.delete_index!
|
431
446
|
end
|
432
447
|
|
448
|
+
it "should copy only settings" do
|
449
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
450
|
+
begin
|
451
|
+
@index.clear_index
|
452
|
+
Algolia.delete_index index.name
|
453
|
+
rescue
|
454
|
+
end
|
455
|
+
|
456
|
+
res = @index.set_settings!({
|
457
|
+
'searchableAttributes' => ['one'],
|
458
|
+
})
|
459
|
+
|
460
|
+
@index.wait_task(res['taskID'])
|
461
|
+
Algolia.copy_settings!(@index.name, index.name)
|
462
|
+
@index.delete_index!
|
463
|
+
|
464
|
+
index.get_settings['searchableAttributes'].should eq(['one'])
|
465
|
+
index.delete_index!
|
466
|
+
end
|
467
|
+
|
468
|
+
it "should copy only synonyms" do
|
469
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
470
|
+
begin
|
471
|
+
@index.clear_index
|
472
|
+
Algolia.delete_index index.name
|
473
|
+
rescue
|
474
|
+
end
|
475
|
+
|
476
|
+
@index.save_synonym!('foo', {
|
477
|
+
:objectID => 'foo', :synonyms => ['car', 'vehicle', 'auto'], :type => 'synonym',
|
478
|
+
})
|
479
|
+
|
480
|
+
Algolia.copy_synonyms!(@index.name, index.name)
|
481
|
+
@index.delete_index!
|
482
|
+
|
483
|
+
index.get_synonym('foo')['objectID'].should eq('foo')
|
484
|
+
index.delete_index!
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should copy only rules" do
|
488
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
489
|
+
begin
|
490
|
+
@index.clear_index
|
491
|
+
Algolia.delete_index index.name
|
492
|
+
rescue
|
493
|
+
end
|
494
|
+
|
495
|
+
@index.save_rule!('bar', {
|
496
|
+
:objectID => 'bar',
|
497
|
+
:condition => {:pattern => 'test', :anchoring => 'contains'},
|
498
|
+
:consequence => {:params => {:query => 'this is better'}}
|
499
|
+
})
|
500
|
+
|
501
|
+
Algolia.copy_rules!(@index.name, index.name)
|
502
|
+
@index.delete_index!
|
503
|
+
|
504
|
+
index.get_rule('bar')['objectID'].should eq('bar')
|
505
|
+
index.delete_index!
|
506
|
+
end
|
507
|
+
|
433
508
|
it "should copy parts of the index only" do
|
434
509
|
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
435
510
|
begin
|
@@ -1056,6 +1131,22 @@ describe 'Client' do
|
|
1056
1131
|
@index.search_synonyms('')['nbHits'].should eq(0)
|
1057
1132
|
end
|
1058
1133
|
|
1134
|
+
it "should replace all synonyms" do
|
1135
|
+
@index.batch_synonyms! ([
|
1136
|
+
{:objectID => '1', :type => 'synonym', :synonyms => ['San Francisco', 'SF']},
|
1137
|
+
{:objectID => '2', :type => 'altCorrection1', :word => 'foo', :corrections => ['st']}
|
1138
|
+
])
|
1139
|
+
|
1140
|
+
@index.replace_all_synonyms! ([
|
1141
|
+
{:objectID => '3', :type => 'synonym', :synonyms => ['San Francisco', 'SF']},
|
1142
|
+
{:objectID => '4', :type => 'altCorrection1', :word => 'bar', :corrections => ['st']}
|
1143
|
+
])
|
1144
|
+
|
1145
|
+
synonym = @index.get_synonym('4')['objectID'].should eq('4')
|
1146
|
+
synonyms_search = @index.search_synonyms('')['hits']
|
1147
|
+
synonyms_search.size.should eq(2)
|
1148
|
+
end
|
1149
|
+
|
1059
1150
|
it 'should test Query Rules' do
|
1060
1151
|
rule_1 = {
|
1061
1152
|
:objectID => '42',
|
@@ -1100,6 +1191,29 @@ describe 'Client' do
|
|
1100
1191
|
@index.search_rules('')['nbHits'].should eq(0)
|
1101
1192
|
end
|
1102
1193
|
|
1194
|
+
it "should replace all rules" do
|
1195
|
+
rule_1 = {
|
1196
|
+
:objectID => '1',
|
1197
|
+
:condition => {:pattern => 'test', :anchoring => 'contains'},
|
1198
|
+
:consequence => {:params => {:query => 'this is better'}}
|
1199
|
+
}
|
1200
|
+
rule_2 = {
|
1201
|
+
:objectID => '2',
|
1202
|
+
:condition => {:pattern => 'Pura', :anchoring => 'contains'},
|
1203
|
+
:consequence => {:params => {:query => 'Pura Vida'}}
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
@index.batch_rules! [rule_1, rule_2]
|
1207
|
+
|
1208
|
+
rule_1[:objectID] = '3'
|
1209
|
+
rule_2[:objectID] = '4'
|
1210
|
+
@index.replace_all_rules!([rule_1, rule_2])
|
1211
|
+
|
1212
|
+
@index.get_rule('4')['objectID'].should eq('4')
|
1213
|
+
rules_search = @index.search_rules('')['hits']
|
1214
|
+
rules_search.size.should eq(2)
|
1215
|
+
end
|
1216
|
+
|
1103
1217
|
it 'should not save a query rule with an empty objectID' do
|
1104
1218
|
rule = {
|
1105
1219
|
:objectID => '',
|
data/spec/spec_helper.rb
CHANGED
@@ -44,6 +44,15 @@ def safe_index_name(name)
|
|
44
44
|
"TRAVIS_RUBY_#{name}-#{id}"
|
45
45
|
end
|
46
46
|
|
47
|
+
# avoid concurrent access to the same index and follows the CTS standards.
|
48
|
+
def index_name(name)
|
49
|
+
date = DateTime.now.strftime('%Y-%m-%d_%H:%M:%S')
|
50
|
+
|
51
|
+
instance = ENV['TRAVIS'].to_s == 'true' ? ENV['TRAVIS_JOB_NUMBER'] : 'unknown'
|
52
|
+
|
53
|
+
'ruby_%s_%s_%s' % [date, instance, name]
|
54
|
+
end
|
55
|
+
|
47
56
|
def auto_retry(options = {})
|
48
57
|
return if !block_given?
|
49
58
|
|
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.
|
4
|
+
version: 1.24.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-11-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -105,6 +105,7 @@ files:
|
|
105
105
|
- Rakefile
|
106
106
|
- algoliasearch.gemspec
|
107
107
|
- contacts.json
|
108
|
+
- lib/algolia/account_client.rb
|
108
109
|
- lib/algolia/analytics.rb
|
109
110
|
- lib/algolia/client.rb
|
110
111
|
- lib/algolia/error.rb
|
@@ -114,6 +115,7 @@ files:
|
|
114
115
|
- lib/algolia/webmock.rb
|
115
116
|
- lib/algoliasearch.rb
|
116
117
|
- resources/ca-bundle.crt
|
118
|
+
- spec/account_client_spec.rb
|
117
119
|
- spec/client_spec.rb
|
118
120
|
- spec/mock_spec.rb
|
119
121
|
- spec/spec_helper.rb
|
@@ -143,7 +145,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
145
|
version: '0'
|
144
146
|
requirements: []
|
145
147
|
rubyforge_project:
|
146
|
-
rubygems_version: 2.7.
|
148
|
+
rubygems_version: 2.7.8
|
147
149
|
signing_key:
|
148
150
|
specification_version: 4
|
149
151
|
summary: A simple Ruby client for the algolia.com REST API
|