algoliasearch 1.2.2 → 1.2.3
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 +7 -7
- data/ChangeLog +4 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +23 -0
- data/README.md +121 -66
- data/algoliasearch.gemspec +1 -1
- data/lib/algolia/client.rb +0 -12
- data/lib/algolia/index.rb +5 -2
- data/lib/algolia/protocol.rb +5 -5
- data/lib/algolia/version.rb +1 -1
- data/spec/client_spec.rb +437 -5
- data/spec/spec_helper.rb +11 -0
- metadata +79 -59
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: c168df1007c65f3a05fdac4a6d85abb0c032307b
|
|
4
|
+
data.tar.gz: 428cd9b8e97c21fdece377ef64e5a8b78118470c
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: a9443ef278cfc1767212702a70f7d335f18b710f77538014c6e327e0bb165ab676f1044594a323a83718efec5e4bce00efb2dd2efc209f48d2143984260a06c5
|
|
7
|
+
data.tar.gz: 9ded465bc3d8f4486c96693ea14cfecb6f0ba2a4249931f8c15fae518f3ba2bf82cd6827b0da0b9462c305a799b2fc86e7a0b6a677269dd43ba8d3adff5445da
|
data/ChangeLog
CHANGED
data/Gemfile
CHANGED
|
@@ -5,6 +5,7 @@ gem 'json', '>= 1.5.1'
|
|
|
5
5
|
gem 'rubysl', '~> 2.0', platform: :rbx
|
|
6
6
|
|
|
7
7
|
group :development do
|
|
8
|
+
gem 'coveralls'
|
|
8
9
|
gem 'travis'
|
|
9
10
|
gem 'rake'
|
|
10
11
|
gem 'rdoc'
|
|
@@ -17,4 +18,5 @@ group :test do
|
|
|
17
18
|
gem 'redgreen'
|
|
18
19
|
gem 'autotest-growl'
|
|
19
20
|
gem 'webmock'
|
|
21
|
+
gem 'simplecov'
|
|
20
22
|
end
|
data/Gemfile.lock
CHANGED
|
@@ -10,9 +10,16 @@ GEM
|
|
|
10
10
|
autotest-growl (0.2.16)
|
|
11
11
|
backports (3.4.0)
|
|
12
12
|
coderay (1.1.0)
|
|
13
|
+
coveralls (0.7.0)
|
|
14
|
+
multi_json (~> 1.3)
|
|
15
|
+
rest-client
|
|
16
|
+
simplecov (>= 0.7)
|
|
17
|
+
term-ansicolor
|
|
18
|
+
thor
|
|
13
19
|
crack (0.4.1)
|
|
14
20
|
safe_yaml (~> 0.9.0)
|
|
15
21
|
diff-lcs (1.2.5)
|
|
22
|
+
docile (1.1.2)
|
|
16
23
|
ethon (0.6.2)
|
|
17
24
|
ffi (>= 1.3.0)
|
|
18
25
|
mime-types (~> 1.18)
|
|
@@ -36,6 +43,9 @@ GEM
|
|
|
36
43
|
json (1.8.1-java)
|
|
37
44
|
launchy (2.4.2)
|
|
38
45
|
addressable (~> 2.3)
|
|
46
|
+
launchy (2.4.2-java)
|
|
47
|
+
addressable (~> 2.3)
|
|
48
|
+
spoon (~> 0.0.1)
|
|
39
49
|
method_source (0.8.2)
|
|
40
50
|
mime-types (1.25.1)
|
|
41
51
|
multi_json (1.8.2)
|
|
@@ -57,6 +67,8 @@ GEM
|
|
|
57
67
|
rdoc (4.1.0)
|
|
58
68
|
json (~> 1.4)
|
|
59
69
|
redgreen (1.2.2)
|
|
70
|
+
rest-client (1.6.7)
|
|
71
|
+
mime-types (>= 1.16)
|
|
60
72
|
rspec (2.14.1)
|
|
61
73
|
rspec-core (~> 2.14.0)
|
|
62
74
|
rspec-expectations (~> 2.14.0)
|
|
@@ -268,11 +280,20 @@ GEM
|
|
|
268
280
|
rubysl-yaml (2.0.4)
|
|
269
281
|
rubysl-zlib (2.0.1)
|
|
270
282
|
safe_yaml (0.9.7)
|
|
283
|
+
simplecov (0.8.2)
|
|
284
|
+
docile (~> 1.1.0)
|
|
285
|
+
multi_json
|
|
286
|
+
simplecov-html (~> 0.8.0)
|
|
287
|
+
simplecov-html (0.8.0)
|
|
271
288
|
slop (3.4.7)
|
|
272
289
|
spoon (0.0.4)
|
|
273
290
|
ffi
|
|
274
291
|
sys-uname (0.9.2)
|
|
275
292
|
ffi (>= 1.0.0)
|
|
293
|
+
term-ansicolor (1.2.2)
|
|
294
|
+
tins (~> 0.8)
|
|
295
|
+
thor (0.18.1)
|
|
296
|
+
tins (0.13.1)
|
|
276
297
|
travis (1.6.6)
|
|
277
298
|
addressable (~> 2.3)
|
|
278
299
|
backports
|
|
@@ -299,6 +320,7 @@ DEPENDENCIES
|
|
|
299
320
|
autotest
|
|
300
321
|
autotest-fsevent
|
|
301
322
|
autotest-growl
|
|
323
|
+
coveralls
|
|
302
324
|
httpclient (~> 2.3)
|
|
303
325
|
json (>= 1.5.1)
|
|
304
326
|
rake
|
|
@@ -306,5 +328,6 @@ DEPENDENCIES
|
|
|
306
328
|
redgreen
|
|
307
329
|
rspec (>= 2.5.0)
|
|
308
330
|
rubysl (~> 2.0)
|
|
331
|
+
simplecov
|
|
309
332
|
travis
|
|
310
333
|
webmock
|
data/README.md
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
Algolia Search API Client for Ruby
|
|
2
2
|
==================
|
|
3
3
|
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
|
|
4
8
|
[Algolia Search](http://www.algolia.com) is a search API that provides hosted full-text, numerical and faceted search.
|
|
5
9
|
Algolia’s Search API makes it easy to deliver a great search experience in your apps & websites providing:
|
|
6
10
|
|
|
@@ -15,20 +19,23 @@ Algolia’s Search API makes it easy to deliver a great search experience in you
|
|
|
15
19
|
|
|
16
20
|
This Ruby client let you easily use the Algolia Search API from your backend. It wraps [Algolia's REST API](http://www.algolia.com/doc/rest_api).
|
|
17
21
|
|
|
18
|
-
[](https://travis-ci.org/algolia/algoliasearch-client-ruby) [](http://badge.fury.io/rb/algoliasearch) [](https://codeclimate.com/github/algolia/algoliasearch-client-ruby)
|
|
22
|
+
[](https://travis-ci.org/algolia/algoliasearch-client-ruby) [](http://badge.fury.io/rb/algoliasearch) [](https://codeclimate.com/github/algolia/algoliasearch-client-ruby) [](https://coveralls.io/r/algolia/algoliasearch-client-ruby)
|
|
23
|
+
|
|
24
|
+
|
|
19
25
|
|
|
20
26
|
Table of Content
|
|
21
27
|
-------------
|
|
22
28
|
**Get started**
|
|
23
29
|
|
|
24
|
-
1. [Setup](#setup)
|
|
30
|
+
1. [Setup](#setup)
|
|
25
31
|
1. [Quick Start](#quick-start)
|
|
32
|
+
1. [Online documentation](#online-documentation)
|
|
26
33
|
|
|
27
34
|
**Commands reference**
|
|
28
35
|
|
|
29
|
-
1. [Search](#search)
|
|
30
36
|
1. [Add a new object](#add-a-new-object-in-the-index)
|
|
31
37
|
1. [Update an object](#update-an-existing-object-in-the-index)
|
|
38
|
+
1. [Search](#search)
|
|
32
39
|
1. [Get an object](#get-an-object)
|
|
33
40
|
1. [Delete an object](#delete-an-object)
|
|
34
41
|
1. [Index settings](#index-settings)
|
|
@@ -43,10 +50,16 @@ Table of Content
|
|
|
43
50
|
1. [Logs](#logs)
|
|
44
51
|
1. [Mock](#mock)
|
|
45
52
|
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
|
|
46
56
|
Setup
|
|
47
57
|
-------------
|
|
48
58
|
To setup your project, follow these steps:
|
|
49
59
|
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
|
|
50
63
|
1. Install AlgoliaSearch using <code>gem install algoliasearch</code>.
|
|
51
64
|
2. Initialize the client with your ApplicationID and API-Key. You can find all of them on [your Algolia account](http://www.algolia.com/users/edit).
|
|
52
65
|
|
|
@@ -58,8 +71,11 @@ Algolia.init :application_id => "YourApplicationID",
|
|
|
58
71
|
:api_key => "YourAPIKey"
|
|
59
72
|
```
|
|
60
73
|
|
|
74
|
+
|
|
75
|
+
|
|
61
76
|
Quick Start
|
|
62
77
|
-------------
|
|
78
|
+
|
|
63
79
|
This quick start is a 30 seconds tutorial where you can discover how to index and search objects.
|
|
64
80
|
|
|
65
81
|
Without any prior-configuration, you can index [500 contacts](https://github.com/algolia/algoliasearch-client-ruby/blob/master/contacts.json) in the ```contacts``` index with the following code:
|
|
@@ -85,6 +101,7 @@ Settings can be customized to tune the search behavior. For example you can add
|
|
|
85
101
|
```ruby
|
|
86
102
|
index.set_settings({"customRanking" => ["desc(followers)"]})
|
|
87
103
|
```
|
|
104
|
+
|
|
88
105
|
You can also configure the list of attributes you want to index by order of importance (first = most important):
|
|
89
106
|
```ruby
|
|
90
107
|
index.set_settings({"attributesToIndex" => ["lastname", "firstname", "company",
|
|
@@ -97,13 +114,91 @@ puts index.search('or').to_json
|
|
|
97
114
|
puts index.search('jim').to_json
|
|
98
115
|
```
|
|
99
116
|
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
Online Documentation
|
|
121
|
+
----------------
|
|
122
|
+
|
|
123
|
+
Check our [online documentation](http://www.algolia.com/doc):
|
|
124
|
+
* [Initial Import](http://www.algolia.com/doc#InitialImport)
|
|
125
|
+
* [Ranking & Relevance](http://www.algolia.com/doc#RankingRelevance)
|
|
126
|
+
* [Settings](http://www.algolia.com/doc#Settings)
|
|
127
|
+
* [Search](http://www.algolia.com/doc#Search)
|
|
128
|
+
* [Incremental Updates](http://www.algolia.com/doc#IncrementalUpdates)
|
|
129
|
+
* [Reindexing](http://www.algolia.com/doc#Reindexing)
|
|
130
|
+
* [Numeric-Search](http://www.algolia.com/doc#Numeric-Search)
|
|
131
|
+
* [Category-Search](http://www.algolia.com/doc#Category-Search)
|
|
132
|
+
* [Faceting](http://www.algolia.com/doc#Faceting)
|
|
133
|
+
* [Geo-Search](http://www.algolia.com/doc#Geo-Search)
|
|
134
|
+
* [Security](http://www.algolia.com/doc#Security)
|
|
135
|
+
* [Indexing Several Types](http://www.algolia.com/doc#IndexingSeveralTypes)
|
|
136
|
+
* [REST API](http://www.algolia.com/doc/rest)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
Add a new object in the Index
|
|
145
|
+
-------------
|
|
146
|
+
|
|
147
|
+
Each entry in an index has a unique identifier called `objectID`. You have two ways to add en entry in the index:
|
|
148
|
+
|
|
149
|
+
1. Using automatic `objectID` assignement, you will be able to retrieve it in the answer.
|
|
150
|
+
2. Passing your own `objectID`
|
|
151
|
+
|
|
152
|
+
You don't need to explicitely create an index, it will be automatically created the first time you add an object.
|
|
153
|
+
Objects are schema less, you don't need any configuration to start indexing. The settings section provide details about advanced settings.
|
|
154
|
+
|
|
155
|
+
Example with automatic `objectID` assignement:
|
|
156
|
+
|
|
157
|
+
```ruby
|
|
158
|
+
res = index.add_object({"firstname" => "Jimmie",
|
|
159
|
+
"lastname" => "Barninger"})
|
|
160
|
+
puts "ObjectID=" + res["objectID"]
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Example with manual `objectID` assignement:
|
|
164
|
+
|
|
165
|
+
```ruby
|
|
166
|
+
res = index.add_object({"firstname" => "Jimmie",
|
|
167
|
+
"lastname" => "Barninger"}, "myID")
|
|
168
|
+
puts "ObjectID=" + res["objectID"]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
Update an existing object in the Index
|
|
172
|
+
-------------
|
|
173
|
+
|
|
174
|
+
You have two options to update an existing object:
|
|
175
|
+
|
|
176
|
+
1. Replace all its attributes.
|
|
177
|
+
2. Replace only some attributes.
|
|
178
|
+
|
|
179
|
+
Example to replace all the content of an existing object:
|
|
180
|
+
|
|
181
|
+
```ruby
|
|
182
|
+
index.save_object({"firstname" => "Jimmie",
|
|
183
|
+
"lastname" => "Barninger",
|
|
184
|
+
"city" => "New York",
|
|
185
|
+
"objectID" => "myID"})
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
Example to update only the city attribute of an existing object:
|
|
189
|
+
|
|
190
|
+
```ruby
|
|
191
|
+
index.partial_update_object({"city" => "San Francisco",
|
|
192
|
+
"objectID" => "myID"})
|
|
193
|
+
```
|
|
194
|
+
|
|
100
195
|
Search
|
|
101
196
|
-------------
|
|
102
|
-
|
|
197
|
+
**Opening note:** If you are building a web application, you may be more interested in using our [javascript client](https://github.com/algolia/algoliasearch-client-js) to send queries. It brings two benefits: (i) your users get a better response time by avoiding to go through your servers, and (ii) it will offload your servers of unnecessary tasks.
|
|
103
198
|
|
|
104
|
-
To perform a search, you just need to initialize the index and perform a call to the search function
|
|
105
|
-
You can use the following optional arguments:
|
|
199
|
+
To perform a search, you just need to initialize the index and perform a call to the search function.
|
|
106
200
|
|
|
201
|
+
You can use the following optional arguments:
|
|
107
202
|
|
|
108
203
|
### Query parameters
|
|
109
204
|
|
|
@@ -129,6 +224,7 @@ You can use the following optional arguments:
|
|
|
129
224
|
* **insideBoundingBox**: search entries inside a given area defined by the two extreme points of a rectangle (defined by 4 floats: p1Lat,p1Lng,p2Lat,p2Lng).<br/>For example `insideBoundingBox=47.3165,4.9665,47.3424,5.0201`).<br/>At indexing, you should specify geoloc of an object with the _geoloc attribute (in the form `{"_geoloc":{"lat":48.853409, "lng":2.348800}}`)
|
|
130
225
|
|
|
131
226
|
#### Parameters to control results content
|
|
227
|
+
|
|
132
228
|
* **attributesToRetrieve**: a string that contains the list of object attributes you want to retrieve (let you minimize the answer size).<br/> Attributes are separated with a comma (for example `"name,address"`), you can also use a string array encoding (for example `["name","address"]` ). By default, all attributes are retrieved. You can also use `*` to retrieve all values when an **attributesToRetrieve** setting is specified for your index.
|
|
133
229
|
* **attributesToHighlight**: a string that contains the list of attributes you want to highlight according to the query. Attributes are separated by a comma. You can also use a string array encoding (for example `["name","address"]`). If an attribute has no match for the query, the raw value is returned. By default all indexed text attributes are highlighted. You can use `*` if you want to highlight all textual attributes. Numerical attributes are not highlighted. A matchLevel is returned for each highlighted attribute and can contain:
|
|
134
230
|
* **full**: if all the query terms were found in the attribute,
|
|
@@ -136,6 +232,7 @@ You can use the following optional arguments:
|
|
|
136
232
|
* **none**: if none of the query terms were found.
|
|
137
233
|
* **attributesToSnippet**: a string that contains the list of attributes to snippet alongside the number of words to return (syntax is `attributeName:nbWords`). Attributes are separated by a comma (Example: `attributesToSnippet=name:10,content:10`). <br/>You can also use a string array encoding (Example: `attributesToSnippet: ["name:10","content:10"]`). By default no snippet is computed.
|
|
138
234
|
* **getRankingInfo**: if set to 1, the result hits will contain ranking information in **_rankingInfo** attribute.
|
|
235
|
+
|
|
139
236
|
|
|
140
237
|
#### Numeric search parameters
|
|
141
238
|
* **numericFilters**: a string that contains the list of numeric filters you want to apply separated by a comma. The syntax of one filter is `attributeName` followed by `operand` followed by `value`. Supported operands are `<`, `<=`, `=`, `>` and `>=`.
|
|
@@ -145,7 +242,7 @@ You can use the following optional arguments:
|
|
|
145
242
|
* **tagFilters**: filter the query by a set of tags. You can AND tags by separating them by commas. To OR tags, you must add parentheses. For example, `tags=tag1,(tag2,tag3)` means *tag1 AND (tag2 OR tag3)*. You can also use a string array encoding, for example `tagFilters: ["tag1",["tag2","tag3"]]` means *tag1 AND (tag2 OR tag3)*.<br/>At indexing, tags should be added in the **_tags** attribute of objects (for example `{"_tags":["tag1","tag2"]}`).
|
|
146
243
|
|
|
147
244
|
#### Faceting parameters
|
|
148
|
-
* **facetFilters**: filter the query by a list of facets. Facets are separated by commas and each facet is encoded as `attributeName:value`. For example: `facetFilters=category:Book,author:John%20Doe`. You can also use a string array encoding (for example `["category:Book","author:John%20Doe"]`).
|
|
245
|
+
* **facetFilters**: filter the query by a list of facets. Facets are separated by commas and each facet is encoded as `attributeName:value`. To OR facets, you must add parentheses. For example: `facetFilters=(category:Book,category:Movie),author:John%20Doe`. You can also use a string array encoding (for example `[["category:Book","category:Movie"],"author:John%20Doe"]`).
|
|
149
246
|
* **facets**: List of object attributes that you want to use for faceting. <br/>Attributes are separated with a comma (for example `"category,author"` ). You can also use a JSON string array encoding (for example `["category","author"]` ). Only attributes that have been added in **attributesForFaceting** index setting can be used in this parameter. You can also use `*` to perform faceting on all attributes specified in **attributesForFaceting**.
|
|
150
247
|
|
|
151
248
|
#### Distinct parameter
|
|
@@ -192,57 +289,6 @@ The server response will look like:
|
|
|
192
289
|
}
|
|
193
290
|
```
|
|
194
291
|
|
|
195
|
-
Add a new object in the Index
|
|
196
|
-
-------------
|
|
197
|
-
|
|
198
|
-
Each entry in an index has a unique identifier called `objectID`. You have two ways to add en entry in the index:
|
|
199
|
-
|
|
200
|
-
1. Using automatic `objectID` assignement, you will be able to retrieve it in the answer.
|
|
201
|
-
2. Passing your own `objectID`
|
|
202
|
-
|
|
203
|
-
You don't need to explicitely create an index, it will be automatically created the first time you add an object.
|
|
204
|
-
Objects are schema less, you don't need any configuration to start indexing. The settings section provide details about advanced settings.
|
|
205
|
-
|
|
206
|
-
Example with automatic `objectID` assignement:
|
|
207
|
-
|
|
208
|
-
```ruby
|
|
209
|
-
res = index.add_object({"firstname" => "Jimmie",
|
|
210
|
-
"lastname" => "Barninger"})
|
|
211
|
-
puts "ObjectID=" + res["objectID"]
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
Example with manual `objectID` assignement:
|
|
215
|
-
|
|
216
|
-
```ruby
|
|
217
|
-
res = index.add_object({"firstname" => "Jimmie",
|
|
218
|
-
"lastname" => "Barninger"}, "myID")
|
|
219
|
-
puts "ObjectID=" + res["objectID"]
|
|
220
|
-
```
|
|
221
|
-
|
|
222
|
-
Update an existing object in the Index
|
|
223
|
-
-------------
|
|
224
|
-
|
|
225
|
-
You have two options to update an existing object:
|
|
226
|
-
|
|
227
|
-
1. Replace all its attributes.
|
|
228
|
-
2. Replace only some attributes.
|
|
229
|
-
|
|
230
|
-
Example to replace all the content of an existing object:
|
|
231
|
-
|
|
232
|
-
```ruby
|
|
233
|
-
index.save_object({"firstname" => "Jimmie",
|
|
234
|
-
"lastname" => "Barninger",
|
|
235
|
-
"city" => "New York",
|
|
236
|
-
"objectID" => "myID"})
|
|
237
|
-
```
|
|
238
|
-
|
|
239
|
-
Example to update only the city attribute of an existing object:
|
|
240
|
-
|
|
241
|
-
```ruby
|
|
242
|
-
index.partial_update_object({"city" => "San Francisco",
|
|
243
|
-
"objectID" => "myID"})
|
|
244
|
-
```
|
|
245
|
-
|
|
246
292
|
Get an object
|
|
247
293
|
-------------
|
|
248
294
|
|
|
@@ -269,7 +315,8 @@ index.delete_object("myID")
|
|
|
269
315
|
Index Settings
|
|
270
316
|
-------------
|
|
271
317
|
|
|
272
|
-
You can retrieve all settings using the `
|
|
318
|
+
You can retrieve all settings using the `get_settings` function. The result will contains the following attributes:
|
|
319
|
+
|
|
273
320
|
|
|
274
321
|
#### Indexing parameters
|
|
275
322
|
* **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, but you should update it to get optimal results.<br/>This parameter has two important uses:
|
|
@@ -292,6 +339,7 @@ For example `"customRanking" => ["desc(population)", "asc(name)"]`
|
|
|
292
339
|
* **prefixAll**: all query words are interpreted as prefixes,
|
|
293
340
|
* **prefixLast**: only the last word is interpreted as a prefix (default behavior),
|
|
294
341
|
* **prefixNone**: no query word is interpreted as a prefix. This option is not recommended.
|
|
342
|
+
* **slaves**: The list of indexes on which you want to replicate all write operations. In order to get response times in milliseconds, we pre-compute part of the ranking during indexing. If you want to use different ranking configurations depending of the use-case, you need to create one index per ranking configuration. This option enables you to perform write operations only on this index, and to automatically update slave indexes with the same operations.
|
|
295
343
|
|
|
296
344
|
#### Default query parameters (can be overwrite by query)
|
|
297
345
|
* **minWordSizefor1Typo**: (integer) the minimum number of characters to accept one typo (default = 3).
|
|
@@ -329,22 +377,21 @@ You can delete an index using its name:
|
|
|
329
377
|
|
|
330
378
|
```ruby
|
|
331
379
|
index = Algolia::Index.new("contacts")
|
|
332
|
-
index.
|
|
380
|
+
index.delete_index
|
|
333
381
|
```
|
|
334
382
|
|
|
335
383
|
Clear an index
|
|
336
384
|
-------------
|
|
337
|
-
|
|
338
385
|
You can delete the index content without removing settings and index specific API keys with the clearIndex command:
|
|
339
386
|
|
|
340
387
|
```ruby
|
|
341
|
-
index.
|
|
388
|
+
index.clear_index
|
|
342
389
|
```
|
|
343
390
|
|
|
344
391
|
Wait indexing
|
|
345
392
|
-------------
|
|
346
393
|
|
|
347
|
-
All write operations return a `taskID` when the job is securely stored on our infrastructure but not when the job is published in your index. Even if it's extremely fast, you can easily ensure indexing is complete using
|
|
394
|
+
All write operations return a `taskID` when the job is securely stored on our infrastructure but not when the job is published in your index. Even if it's extremely fast, you can easily ensure indexing is complete using the same method with a `!`.
|
|
348
395
|
|
|
349
396
|
For example, to wait for indexing of a new object:
|
|
350
397
|
```ruby
|
|
@@ -352,13 +399,14 @@ res = index.add_object!({"firstname" => "Jimmie",
|
|
|
352
399
|
"lastname" => "Barninger"})
|
|
353
400
|
```
|
|
354
401
|
|
|
402
|
+
|
|
355
403
|
If you want to ensure multiple objects have been indexed, you can only check the biggest taskID with `wait_task`.
|
|
356
404
|
|
|
357
405
|
Batch writes
|
|
358
406
|
-------------
|
|
359
407
|
|
|
360
408
|
You may want to perform multiple operations with one API call to reduce latency.
|
|
361
|
-
We expose
|
|
409
|
+
We expose three methods to perform batch:
|
|
362
410
|
* `add_objects`: add an array of object using automatic `objectID` assignement
|
|
363
411
|
* `save_objects`: add or update an array of object that contains an `objectID` attribute
|
|
364
412
|
* `partial_update_objects`: partially update an array of objects that contain an `objectID` attribute (only specified attributes will be updated, other will remain unchanged)
|
|
@@ -389,6 +437,8 @@ res = index.partial_update_objects([{"firstname" => "Jimmie",
|
|
|
389
437
|
"objectID" => "myID2"}])
|
|
390
438
|
```
|
|
391
439
|
|
|
440
|
+
|
|
441
|
+
|
|
392
442
|
Security / User API Keys
|
|
393
443
|
-------------
|
|
394
444
|
|
|
@@ -422,11 +472,13 @@ puts res['key']
|
|
|
422
472
|
res = index.add_user_key(["search"])
|
|
423
473
|
puts res['key']
|
|
424
474
|
```
|
|
475
|
+
|
|
425
476
|
You can also create an API Key with advanced restrictions:
|
|
426
477
|
|
|
427
478
|
* Add a validity period: the key will be valid only for a specific period of time (in seconds),
|
|
428
479
|
* 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 origin 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 content by massively querying the index.
|
|
429
480
|
|
|
481
|
+
|
|
430
482
|
Note: If you are sending the query through your servers, you must use the `Algolia.with_rate_limits("EndUserIP", "APIKeyWithRateLimit") do ... end` block to enable rate-limit.
|
|
431
483
|
|
|
432
484
|
* 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 content by massively querying the index.
|
|
@@ -534,8 +586,8 @@ describe 'With a mocked client' do
|
|
|
534
586
|
index = Algolia::Index.new("friends")
|
|
535
587
|
index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
|
|
536
588
|
index.search('').should == {} # mocked
|
|
537
|
-
index.
|
|
538
|
-
index.
|
|
589
|
+
index.clear_index
|
|
590
|
+
index.delete_index
|
|
539
591
|
end
|
|
540
592
|
|
|
541
593
|
after(:each) do
|
|
@@ -544,3 +596,6 @@ describe 'With a mocked client' do
|
|
|
544
596
|
|
|
545
597
|
end
|
|
546
598
|
```
|
|
599
|
+
|
|
600
|
+
|
|
601
|
+
|
data/algoliasearch.gemspec
CHANGED
data/lib/algolia/client.rb
CHANGED
|
@@ -93,18 +93,6 @@ module Algolia
|
|
|
93
93
|
return JSON.parse(response.content)
|
|
94
94
|
end
|
|
95
95
|
|
|
96
|
-
def init_session
|
|
97
|
-
s = Curl::Easy.new
|
|
98
|
-
s.headers[Protocol::HEADER_API_KEY] = api_key
|
|
99
|
-
s.headers[Protocol::HEADER_APP_ID] = application_id
|
|
100
|
-
s.headers["Content-Type"] = "application/json; charset=utf-8"
|
|
101
|
-
s.headers["User-Agent"] = "Algolia for Ruby #{::Algolia::VERSION}"
|
|
102
|
-
s.verbose = true if @debug
|
|
103
|
-
s.cacert = File.join File.dirname(__FILE__), '..', '..', 'resources', 'ca-bundle.crt'
|
|
104
|
-
s.encoding = ''
|
|
105
|
-
s
|
|
106
|
-
end
|
|
107
|
-
|
|
108
96
|
end
|
|
109
97
|
|
|
110
98
|
# Module methods
|
data/lib/algolia/index.rb
CHANGED
|
@@ -16,6 +16,7 @@ module Algolia
|
|
|
16
16
|
def delete
|
|
17
17
|
Algolia.client.delete(Protocol.index_uri(name))
|
|
18
18
|
end
|
|
19
|
+
alias_method :delete_index, :delete
|
|
19
20
|
|
|
20
21
|
# Add an object in this index
|
|
21
22
|
#
|
|
@@ -25,7 +26,7 @@ module Algolia
|
|
|
25
26
|
# (if the attribute already exist the old object will be overridden)
|
|
26
27
|
def add_object(obj, objectID = nil)
|
|
27
28
|
check_object obj
|
|
28
|
-
if objectID.nil?
|
|
29
|
+
if objectID.nil? || objectID.to_s.empty?
|
|
29
30
|
Algolia.client.post(Protocol.index_uri(name), obj.to_json)
|
|
30
31
|
else
|
|
31
32
|
Algolia.client.put(Protocol.object_uri(name, objectID), obj.to_json)
|
|
@@ -232,7 +233,7 @@ module Algolia
|
|
|
232
233
|
# @param objs an array of objects to update (each object must contains a objectID attribute)
|
|
233
234
|
#
|
|
234
235
|
def partial_update_objects!(objs)
|
|
235
|
-
res = partial_update_objects(
|
|
236
|
+
res = partial_update_objects(objs)
|
|
236
237
|
wait_task(res["taskID"])
|
|
237
238
|
return res
|
|
238
239
|
end
|
|
@@ -276,6 +277,7 @@ module Algolia
|
|
|
276
277
|
def clear
|
|
277
278
|
Algolia.client.post(Protocol.clear_uri(name))
|
|
278
279
|
end
|
|
280
|
+
alias_method :clear_index, :clear
|
|
279
281
|
|
|
280
282
|
#
|
|
281
283
|
# Delete the index content and wait end of indexing
|
|
@@ -285,6 +287,7 @@ module Algolia
|
|
|
285
287
|
wait_task(res["taskID"])
|
|
286
288
|
return res
|
|
287
289
|
end
|
|
290
|
+
alias_method :clear_index!, :clear!
|
|
288
291
|
|
|
289
292
|
#
|
|
290
293
|
# Set settings for this index
|
data/lib/algolia/protocol.rb
CHANGED
|
@@ -40,15 +40,15 @@ module Algolia
|
|
|
40
40
|
|
|
41
41
|
# Construct a uri referencing a given Algolia index
|
|
42
42
|
def Protocol.index_uri(index)
|
|
43
|
-
"/#{VERSION}/indexes/#{index}"
|
|
43
|
+
"/#{VERSION}/indexes/#{CGI.escape(index)}"
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
def Protocol.batch_uri(index)
|
|
47
|
-
"
|
|
47
|
+
"#{index_uri(index)}/batch"
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def Protocol.index_operation_uri(index)
|
|
51
|
-
"
|
|
51
|
+
"#{index_uri(index)}/operation"
|
|
52
52
|
end
|
|
53
53
|
|
|
54
54
|
def Protocol.task_uri(index, task_id)
|
|
@@ -57,7 +57,7 @@ module Algolia
|
|
|
57
57
|
|
|
58
58
|
def Protocol.object_uri(index, object_id, params = {})
|
|
59
59
|
params = params.nil? || params.size == 0 ? "" : "?#{to_query(params)}"
|
|
60
|
-
"#{index_uri(index)}/#{object_id}#{params}"
|
|
60
|
+
"#{index_uri(index)}/#{CGI.escape(object_id.to_s)}#{params}"
|
|
61
61
|
end
|
|
62
62
|
|
|
63
63
|
def Protocol.search_uri(index, query, params = {})
|
|
@@ -71,7 +71,7 @@ module Algolia
|
|
|
71
71
|
end
|
|
72
72
|
|
|
73
73
|
def Protocol.partial_object_uri(index, object_id)
|
|
74
|
-
"#{index_uri(index)}/#{object_id}/partial"
|
|
74
|
+
"#{index_uri(index)}/#{CGI.escape(object_id)}/partial"
|
|
75
75
|
end
|
|
76
76
|
|
|
77
77
|
def Protocol.settings_uri(index)
|
data/lib/algolia/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# encoding: UTF-8
|
|
1
2
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
|
2
3
|
|
|
3
4
|
# avoid concurrent access to the same index
|
|
@@ -7,18 +8,40 @@ def safe_index_name(name)
|
|
|
7
8
|
"#{name}_travis-#{id}"
|
|
8
9
|
end
|
|
9
10
|
|
|
11
|
+
def is_present(array, attr, value)
|
|
12
|
+
array.each do |elt|
|
|
13
|
+
if elt[attr] == value
|
|
14
|
+
return true
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
return false
|
|
18
|
+
end
|
|
19
|
+
|
|
10
20
|
describe 'Client' do
|
|
11
21
|
before(:all) do
|
|
12
|
-
@index = Algolia::Index.new(safe_index_name("
|
|
13
|
-
@index.
|
|
22
|
+
@index = Algolia::Index.new(safe_index_name("àlgol?a"))
|
|
23
|
+
@index.delete_index rescue "not fatal"
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
after(:all) do
|
|
27
|
+
@index.delete_index rescue "not fatal"
|
|
14
28
|
end
|
|
15
29
|
|
|
16
30
|
it "should add a simple object" do
|
|
17
|
-
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
|
|
31
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
18
32
|
res = @index.search("john")
|
|
19
33
|
res["hits"].length.should eq(1)
|
|
20
34
|
end
|
|
21
35
|
|
|
36
|
+
it "should partial update a simple object" do
|
|
37
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
38
|
+
res = @index.search("john")
|
|
39
|
+
res["hits"].length.should eq(1)
|
|
40
|
+
@index.partial_update_object!({ :name => "Robert Doe"}, "1")
|
|
41
|
+
res = @index.search("robert")
|
|
42
|
+
res["hits"].length.should eq(1)
|
|
43
|
+
end
|
|
44
|
+
|
|
22
45
|
it "should add a set of objects" do
|
|
23
46
|
@index.add_objects!([
|
|
24
47
|
{ :name => "Another", :email => "another1@example.org" },
|
|
@@ -28,6 +51,22 @@ describe 'Client' do
|
|
|
28
51
|
res["hits"].length.should eq(2)
|
|
29
52
|
end
|
|
30
53
|
|
|
54
|
+
it "should partial update a simple object" do
|
|
55
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
56
|
+
@index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "2")
|
|
57
|
+
res = @index.search("john")
|
|
58
|
+
res["hits"].length.should eq(2)
|
|
59
|
+
@index.partial_update_objects!([{ :name => "Robert Doe", :objectID => "1"}, { :name => "Robert Doe", :objectID => "2"}])
|
|
60
|
+
res = @index.search("robert")
|
|
61
|
+
res["hits"].length.should eq(2)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
it "should save a set of objects with their ids" do
|
|
65
|
+
@index.save_object!({ :name => "objectid", :email => "objectid1@example.org", :objectID => 101 })
|
|
66
|
+
res = @index.search("objectid")
|
|
67
|
+
res["hits"].length.should eq(1)
|
|
68
|
+
end
|
|
69
|
+
|
|
31
70
|
it "should save a set of objects with their ids" do
|
|
32
71
|
@index.save_objects!([
|
|
33
72
|
{ :name => "objectid", :email => "objectid1@example.org", :objectID => 101 },
|
|
@@ -55,7 +94,7 @@ describe 'Client' do
|
|
|
55
94
|
t = Thread.new do
|
|
56
95
|
10.times do
|
|
57
96
|
res = @index.search("john")
|
|
58
|
-
res["hits"].length.should eq(
|
|
97
|
+
res["hits"].length.should eq(2)
|
|
59
98
|
end
|
|
60
99
|
end
|
|
61
100
|
threads << t
|
|
@@ -69,7 +108,7 @@ describe 'Client' do
|
|
|
69
108
|
Process.fork do
|
|
70
109
|
10.times do
|
|
71
110
|
res = @index.search("john")
|
|
72
|
-
res["hits"].length.should eq(
|
|
111
|
+
res["hits"].length.should eq(2)
|
|
73
112
|
end
|
|
74
113
|
end
|
|
75
114
|
end
|
|
@@ -82,6 +121,124 @@ describe 'Client' do
|
|
|
82
121
|
@index.search("")["hits"].length.should eq(0)
|
|
83
122
|
end
|
|
84
123
|
|
|
124
|
+
it "should have another index after" do
|
|
125
|
+
index = Algolia::Index.new(safe_index_name("àlgol?a"))
|
|
126
|
+
begin
|
|
127
|
+
index.delete_index
|
|
128
|
+
sleep 4 # Dirty but temporary
|
|
129
|
+
rescue
|
|
130
|
+
# friends_2 does not exist
|
|
131
|
+
end
|
|
132
|
+
res = Algolia.list_indexes
|
|
133
|
+
is_present(res['items'], 'name', safe_index_name('àlgol?a')).should eq(false)
|
|
134
|
+
index.add_object!({ :name => "Robert" })
|
|
135
|
+
resAfter = Algolia.list_indexes;
|
|
136
|
+
is_present(resAfter['items'], 'name', safe_index_name('àlgol?a')).should eq(true)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it "should get a object" do
|
|
140
|
+
@index.clear_index
|
|
141
|
+
@index.add_object!({:firstname => "Robert"})
|
|
142
|
+
res = @index.search('')
|
|
143
|
+
@index.search("")["nbHits"].should eq(1)
|
|
144
|
+
object = @index.get_object(res['hits'][0]['objectID'])
|
|
145
|
+
object['firstname'].should eq('Robert')
|
|
146
|
+
object = @index.get_object(res['hits'][0]['objectID'], 'firstname')
|
|
147
|
+
object['firstname'].should eq('Robert')
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
it "should delete the object" do
|
|
151
|
+
@index.clear
|
|
152
|
+
@index.add_object!({:firstname => "Robert"})
|
|
153
|
+
res = @index.search('')
|
|
154
|
+
@index.search('')['nbHits'].should eq(1)
|
|
155
|
+
object = @index.delete_object!(res['hits'][0]['objectID'])
|
|
156
|
+
@index.search('')['nbHits'].should eq(0)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
it "should copy the index" do
|
|
160
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
|
161
|
+
begin
|
|
162
|
+
@index.clear_index
|
|
163
|
+
index.delete_index
|
|
164
|
+
rescue
|
|
165
|
+
# friends_2 does not exist
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
@index.add_object!({:firstname => "Robert"})
|
|
169
|
+
@index.search('')['nbHits'].should eq(1)
|
|
170
|
+
|
|
171
|
+
Algolia.copy_index(safe_index_name("àlgol?a"), safe_index_name("àlgol?à"))
|
|
172
|
+
@index.delete_index
|
|
173
|
+
|
|
174
|
+
index.search('')['nbHits'].should eq(1)
|
|
175
|
+
index.delete_index
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
it "should move the index" do
|
|
179
|
+
@index.clear_index rescue "friends does not exist"
|
|
180
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
|
181
|
+
begin
|
|
182
|
+
index.delete_index
|
|
183
|
+
rescue
|
|
184
|
+
# friends_2 does not exist
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
@index.add_object!({:firstname => "Robert"})
|
|
188
|
+
@index.search('')['nbHits'].should eq(1)
|
|
189
|
+
|
|
190
|
+
Algolia.move_index(safe_index_name("àlgol?a"), safe_index_name("àlgol?à"))
|
|
191
|
+
|
|
192
|
+
index.search('')['nbHits'].should eq(1)
|
|
193
|
+
index.delete_index
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
it "should retrieve the object" do
|
|
197
|
+
@index.clear_index rescue "friends does not exist"
|
|
198
|
+
@index.add_object!({:firstname => "Robert"})
|
|
199
|
+
|
|
200
|
+
res = @index.browse
|
|
201
|
+
|
|
202
|
+
res['hits'].size.should eq(1)
|
|
203
|
+
res['hits'][0]['firstname'].should eq("Robert")
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
it "should get logs" do
|
|
207
|
+
res = Algolia.get_logs
|
|
208
|
+
|
|
209
|
+
res['logs'].size.should > 0
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it "shoud accept custom batch" do
|
|
213
|
+
@index.clear_index! rescue "Not fatal"
|
|
214
|
+
request = { "requests" => [
|
|
215
|
+
{
|
|
216
|
+
"action" => "addObject",
|
|
217
|
+
"body" => {"firstname" => "Jimmie",
|
|
218
|
+
"lastname" => "Barninger"}
|
|
219
|
+
},
|
|
220
|
+
{
|
|
221
|
+
"action" => "addObject",
|
|
222
|
+
"body" => {"firstname" => "Warren",
|
|
223
|
+
"lastname" => "Speach"}
|
|
224
|
+
},
|
|
225
|
+
{
|
|
226
|
+
"action" => "updateObject",
|
|
227
|
+
"body" => {"firstname" => "Jimmie",
|
|
228
|
+
"lastname" => "Barninger",
|
|
229
|
+
"objectID" => "43"}
|
|
230
|
+
},
|
|
231
|
+
{
|
|
232
|
+
"action" => "updateObject",
|
|
233
|
+
"body" => {"firstname" => "Warren",
|
|
234
|
+
"lastname" => "Speach"},
|
|
235
|
+
"objectID" => "42"
|
|
236
|
+
}
|
|
237
|
+
]}
|
|
238
|
+
res = @index.batch(request)
|
|
239
|
+
@index.search('')['nbHits'].should eq(4)
|
|
240
|
+
end
|
|
241
|
+
|
|
85
242
|
it "should allow an array of tags" do
|
|
86
243
|
@index.add_object!({ :name => "P1", :_tags => "t1" })
|
|
87
244
|
@index.add_object!({ :name => "P2", :_tags => "t1" })
|
|
@@ -119,4 +276,279 @@ describe 'Client' do
|
|
|
119
276
|
res['facets']['f']['f3'].should be_nil
|
|
120
277
|
end
|
|
121
278
|
|
|
279
|
+
it "should test keys" do
|
|
280
|
+
resIndex = @index.list_user_keys
|
|
281
|
+
newIndexKey = @index.add_user_key(['search'])
|
|
282
|
+
newIndexKey['key'].should_not eq("")
|
|
283
|
+
resIndexAfter = @index.list_user_keys
|
|
284
|
+
resIndex['keys'].size.should eq(resIndexAfter['keys'].size - 1)
|
|
285
|
+
indexKey = @index.get_user_key(newIndexKey['key'])
|
|
286
|
+
indexKey['acl'][0].should eq('search')
|
|
287
|
+
@index.delete_user_key(newIndexKey['key'])
|
|
288
|
+
sleep 1 # Dirty but temporary
|
|
289
|
+
resIndexEnd = @index.list_user_keys
|
|
290
|
+
resIndex['keys'].size.should eq(resIndexEnd['keys'].size)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
res = Algolia.list_user_keys
|
|
294
|
+
newKey = Algolia.add_user_key(['search'])
|
|
295
|
+
newKey['key'].should_not eq("")
|
|
296
|
+
resAfter = Algolia.list_user_keys
|
|
297
|
+
res['keys'].size.should eq(resAfter['keys'].size - 1)
|
|
298
|
+
key = Algolia.get_user_key(newKey['key'])
|
|
299
|
+
key['acl'][0].should eq('search')
|
|
300
|
+
Algolia.delete_user_key(newKey['key'])
|
|
301
|
+
sleep 1 # Dirty but temporary
|
|
302
|
+
resEnd = Algolia.list_user_keys
|
|
303
|
+
res['keys'].size.should eq(resEnd['keys'].size)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
it "should check functions" do
|
|
309
|
+
@index.get_settings
|
|
310
|
+
@index.list_user_keys
|
|
311
|
+
Algolia.list_user_keys
|
|
312
|
+
|
|
313
|
+
end
|
|
314
|
+
|
|
315
|
+
it "should handle slash in objectId" do
|
|
316
|
+
@index.clear_index!()
|
|
317
|
+
@index.add_object!({:firstname => "Robert", :objectID => "A/go/?a"})
|
|
318
|
+
res = @index.search('')
|
|
319
|
+
@index.search("")["nbHits"].should eq(1)
|
|
320
|
+
object = @index.get_object(res['hits'][0]['objectID'])
|
|
321
|
+
object['firstname'].should eq('Robert')
|
|
322
|
+
object = @index.get_object(res['hits'][0]['objectID'], 'firstname')
|
|
323
|
+
object['firstname'].should eq('Robert')
|
|
324
|
+
|
|
325
|
+
@index.save_object!({:firstname => "George", :objectID => "A/go/?a"})
|
|
326
|
+
res = @index.search('')
|
|
327
|
+
@index.search("")["nbHits"].should eq(1)
|
|
328
|
+
object = @index.get_object(res['hits'][0]['objectID'])
|
|
329
|
+
object['firstname'].should eq('George')
|
|
330
|
+
|
|
331
|
+
@index.partial_update_object!({:firstname => "Sylvain", :objectID => "A/go/?a"})
|
|
332
|
+
res = @index.search('')
|
|
333
|
+
@index.search("")["nbHits"].should eq(1)
|
|
334
|
+
object = @index.get_object(res['hits'][0]['objectID'])
|
|
335
|
+
object['firstname'].should eq('Sylvain')
|
|
336
|
+
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
it "Check attributes list_indexes:" do
|
|
340
|
+
res = Algolia.list_indexes
|
|
341
|
+
res.should have_key('items')
|
|
342
|
+
res['items'][0].should have_key('name')
|
|
343
|
+
res['items'][0]['name'].should be_a(String)
|
|
344
|
+
res['items'][0].should have_key('createdAt')
|
|
345
|
+
res['items'][0]['createdAt'].should be_a(String)
|
|
346
|
+
res['items'][0].should have_key('updatedAt')
|
|
347
|
+
res['items'][0]['updatedAt'].should be_a(String)
|
|
348
|
+
res['items'][0].should have_key('entries')
|
|
349
|
+
res['items'][0]['entries'].should be_a(Integer)
|
|
350
|
+
res['items'][0].should have_key('pendingTask')
|
|
351
|
+
[true, false].should include(res['items'][0]['pendingTask'])
|
|
352
|
+
end
|
|
353
|
+
|
|
354
|
+
it 'Check attributes search : ' do
|
|
355
|
+
res = @index.search('')
|
|
356
|
+
res.should have_key('hits')
|
|
357
|
+
res['hits'].should be_a(Array)
|
|
358
|
+
res.should have_key('page')
|
|
359
|
+
res['page'].should be_a(Integer)
|
|
360
|
+
res.should have_key('nbHits')
|
|
361
|
+
res['nbHits'].should be_a(Integer)
|
|
362
|
+
res.should have_key('nbPages')
|
|
363
|
+
res['nbPages'].should be_a(Integer)
|
|
364
|
+
res.should have_key('hitsPerPage')
|
|
365
|
+
res['hitsPerPage'].should be_a(Integer)
|
|
366
|
+
res.should have_key('processingTimeMS')
|
|
367
|
+
res['processingTimeMS'].should be_a(Integer)
|
|
368
|
+
res.should have_key('query')
|
|
369
|
+
res['query'].should be_a(String)
|
|
370
|
+
res.should have_key('params')
|
|
371
|
+
res['params'].should be_a(String)
|
|
372
|
+
end
|
|
373
|
+
|
|
374
|
+
it 'Check attributes delete_index : ' do
|
|
375
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à2"))
|
|
376
|
+
index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
377
|
+
task = index.delete_index()
|
|
378
|
+
task.should have_key('deletedAt')
|
|
379
|
+
task['deletedAt'].should be_a(String)
|
|
380
|
+
task.should have_key('taskID')
|
|
381
|
+
task['taskID'].should be_a(Integer)
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
it 'Check attributes clear_index : ' do
|
|
385
|
+
task = @index.clear_index
|
|
386
|
+
task.should have_key('updatedAt')
|
|
387
|
+
task['updatedAt'].should be_a(String)
|
|
388
|
+
task.should have_key('taskID')
|
|
389
|
+
task['taskID'].should be_a(Integer)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
it 'Check attributes add object : ' do
|
|
393
|
+
task = @index.add_object({ :name => "John Doe", :email => "john@doe.org" })
|
|
394
|
+
task.should have_key('createdAt')
|
|
395
|
+
task['createdAt'].should be_a(String)
|
|
396
|
+
task.should have_key('taskID')
|
|
397
|
+
task['taskID'].should be_a(Integer)
|
|
398
|
+
task.should have_key('objectID')
|
|
399
|
+
task['objectID'].should be_a(String)
|
|
400
|
+
end
|
|
401
|
+
|
|
402
|
+
it 'Check attributes add object id: ' do
|
|
403
|
+
task = @index.add_object({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
404
|
+
task.should have_key('updatedAt')
|
|
405
|
+
task['updatedAt'].should be_a(String)
|
|
406
|
+
task.should have_key('taskID')
|
|
407
|
+
task['taskID'].should be_a(Integer)
|
|
408
|
+
#task.to_s.should eq("")
|
|
409
|
+
task.should have_key('objectID')
|
|
410
|
+
task['objectID'].should be_a(String)
|
|
411
|
+
task['objectID'].should eq("1")
|
|
412
|
+
end
|
|
413
|
+
|
|
414
|
+
it 'Check attributes partial update: ' do
|
|
415
|
+
task = @index.partial_update_object({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
416
|
+
task.should have_key('updatedAt')
|
|
417
|
+
task['updatedAt'].should be_a(String)
|
|
418
|
+
task.should have_key('taskID')
|
|
419
|
+
task['taskID'].should be_a(Integer)
|
|
420
|
+
task.should have_key('objectID')
|
|
421
|
+
task['objectID'].should be_a(String)
|
|
422
|
+
task['objectID'].should eq("1")
|
|
423
|
+
end
|
|
424
|
+
|
|
425
|
+
it 'Check attributes delete object: ' do
|
|
426
|
+
@index.add_object({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
427
|
+
task = @index.delete_object("1")
|
|
428
|
+
task.should have_key('deletedAt')
|
|
429
|
+
task['deletedAt'].should be_a(String)
|
|
430
|
+
task.should have_key('taskID')
|
|
431
|
+
task['taskID'].should be_a(Integer)
|
|
432
|
+
end
|
|
433
|
+
|
|
434
|
+
it 'Check attributes add objects: ' do
|
|
435
|
+
task = @index.add_objects([{ :name => "John Doe", :email => "john@doe.org", :objectID => "1" }])
|
|
436
|
+
task.should have_key('taskID')
|
|
437
|
+
task['taskID'].should be_a(Integer)
|
|
438
|
+
task.should have_key('objectIDs')
|
|
439
|
+
task['objectIDs'].should be_a(Array)
|
|
440
|
+
end
|
|
441
|
+
|
|
442
|
+
it 'Check attributes browse: ' do
|
|
443
|
+
res = @index.browse()
|
|
444
|
+
res.should have_key('hits')
|
|
445
|
+
res['hits'].should be_a(Array)
|
|
446
|
+
res.should have_key('page')
|
|
447
|
+
res['page'].should be_a(Integer)
|
|
448
|
+
res.should have_key('nbHits')
|
|
449
|
+
res['nbHits'].should be_a(Integer)
|
|
450
|
+
res.should have_key('nbPages')
|
|
451
|
+
res['nbPages'].should be_a(Integer)
|
|
452
|
+
res.should have_key('hitsPerPage')
|
|
453
|
+
res['hitsPerPage'].should be_a(Integer)
|
|
454
|
+
res.should have_key('processingTimeMS')
|
|
455
|
+
res['processingTimeMS'].should be_a(Integer)
|
|
456
|
+
res.should have_key('query')
|
|
457
|
+
res['query'].should be_a(String)
|
|
458
|
+
res.should have_key('params')
|
|
459
|
+
res['params'].should be_a(String)
|
|
460
|
+
end
|
|
461
|
+
|
|
462
|
+
it 'Check attributes get settings: ' do
|
|
463
|
+
task = @index.set_settings({})
|
|
464
|
+
task.should have_key('taskID')
|
|
465
|
+
task['taskID'].should be_a(Integer)
|
|
466
|
+
task.should have_key('updatedAt')
|
|
467
|
+
task['updatedAt'].should be_a(String)
|
|
468
|
+
end
|
|
469
|
+
|
|
470
|
+
it 'Check attributes move_index : ' do
|
|
471
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
|
472
|
+
index2 = Algolia::Index.new(safe_index_name("àlgol?à2"))
|
|
473
|
+
index2.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
474
|
+
task = Algolia.move_index(safe_index_name("àlgol?à2"), safe_index_name("àlgol?à"))
|
|
475
|
+
task.should have_key('updatedAt')
|
|
476
|
+
task['updatedAt'].should be_a(String)
|
|
477
|
+
task.should have_key('taskID')
|
|
478
|
+
task['taskID'].should be_a(Integer)
|
|
479
|
+
index.delete_index
|
|
480
|
+
end
|
|
481
|
+
|
|
482
|
+
it 'Check attributes copy_index : ' do
|
|
483
|
+
index = Algolia::Index.new(safe_index_name("àlgol?à"))
|
|
484
|
+
index2 = Algolia::Index.new(safe_index_name("àlgol?à2"))
|
|
485
|
+
index2.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
486
|
+
task = Algolia.copy_index(safe_index_name("àlgol?à2"), safe_index_name("àlgol?à"))
|
|
487
|
+
task.should have_key('updatedAt')
|
|
488
|
+
task['updatedAt'].should be_a(String)
|
|
489
|
+
task.should have_key('taskID')
|
|
490
|
+
task['taskID'].should be_a(Integer)
|
|
491
|
+
index.delete_index
|
|
492
|
+
index2.delete_index
|
|
493
|
+
end
|
|
494
|
+
|
|
495
|
+
it 'Check attributes wait_task : ' do
|
|
496
|
+
task = @index.add_object!({ :name => "John Doe", :email => "john@doe.org" }, "1")
|
|
497
|
+
task = Algolia.client.get(Algolia::Protocol.task_uri(safe_index_name("àlgol?a"), task['objectID']))
|
|
498
|
+
task.should have_key('status')
|
|
499
|
+
task['status'].should be_a(String)
|
|
500
|
+
task.should have_key('pendingTask')
|
|
501
|
+
[true, false].should include(task['pendingTask'])
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
it "Check add keys" do
|
|
505
|
+
newIndexKey = @index.add_user_key(['search'])
|
|
506
|
+
newIndexKey.should have_key('key')
|
|
507
|
+
newIndexKey['key'].should be_a(String)
|
|
508
|
+
newIndexKey.should have_key('createdAt')
|
|
509
|
+
newIndexKey['createdAt'].should be_a(String)
|
|
510
|
+
resIndex = @index.list_user_keys
|
|
511
|
+
resIndex.should have_key('keys')
|
|
512
|
+
resIndex['keys'].should be_a(Array)
|
|
513
|
+
resIndex['keys'][0].should have_key('value')
|
|
514
|
+
resIndex['keys'][0]['value'].should be_a(String)
|
|
515
|
+
resIndex['keys'][0].should have_key('acl')
|
|
516
|
+
resIndex['keys'][0]['acl'].should be_a(Array)
|
|
517
|
+
resIndex['keys'][0].should have_key('validity')
|
|
518
|
+
resIndex['keys'][0]['validity'].should be_a(Integer)
|
|
519
|
+
indexKey = @index.get_user_key(newIndexKey['key'])
|
|
520
|
+
indexKey.should have_key('value')
|
|
521
|
+
indexKey['value'].should be_a(String)
|
|
522
|
+
indexKey.should have_key('acl')
|
|
523
|
+
indexKey['acl'].should be_a(Array)
|
|
524
|
+
indexKey.should have_key('validity')
|
|
525
|
+
indexKey['validity'].should be_a(Integer)
|
|
526
|
+
task = @index.delete_user_key(newIndexKey['key'])
|
|
527
|
+
task.should have_key('deletedAt')
|
|
528
|
+
task['deletedAt'].should be_a(String)
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
it 'Check attributes log : ' do
|
|
532
|
+
logs = Algolia.get_logs()
|
|
533
|
+
logs.should have_key('logs')
|
|
534
|
+
logs['logs'].should be_a(Array)
|
|
535
|
+
logs['logs'][0].should have_key('timestamp')
|
|
536
|
+
logs['logs'][0]['timestamp'].should be_a(String)
|
|
537
|
+
logs['logs'][0].should have_key('method')
|
|
538
|
+
logs['logs'][0]['method'].should be_a(String)
|
|
539
|
+
logs['logs'][0].should have_key('answer_code')
|
|
540
|
+
logs['logs'][0]['answer_code'].should be_a(String)
|
|
541
|
+
logs['logs'][0].should have_key('query_body')
|
|
542
|
+
logs['logs'][0]['query_body'].should be_a(String)
|
|
543
|
+
logs['logs'][0].should have_key('answer')
|
|
544
|
+
logs['logs'][0]['answer'].should be_a(String)
|
|
545
|
+
logs['logs'][0].should have_key('url')
|
|
546
|
+
logs['logs'][0]['url'].should be_a(String)
|
|
547
|
+
logs['logs'][0].should have_key('ip')
|
|
548
|
+
logs['logs'][0]['ip'].should be_a(String)
|
|
549
|
+
logs['logs'][0].should have_key('query_headers')
|
|
550
|
+
logs['logs'][0]['query_headers'].should be_a(String)
|
|
551
|
+
logs['logs'][0].should have_key('sha1')
|
|
552
|
+
logs['logs'][0]['sha1'].should be_a(String)
|
|
553
|
+
end
|
|
122
554
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,74 +1,94 @@
|
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: algoliasearch
|
|
3
|
-
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.2.
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 1.2.3
|
|
5
5
|
platform: ruby
|
|
6
|
-
authors:
|
|
6
|
+
authors:
|
|
7
7
|
- Algolia
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
- !ruby/object:Gem::Dependency
|
|
11
|
+
date: 2014-01-11 00:00:00.000000000 Z
|
|
12
|
+
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
15
14
|
name: httpclient
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
requirements:
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
19
17
|
- - ~>
|
|
20
|
-
- !ruby/object:Gem::Version
|
|
21
|
-
version:
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '2.3'
|
|
22
20
|
type: :runtime
|
|
23
|
-
version_requirements: *id001
|
|
24
|
-
- !ruby/object:Gem::Dependency
|
|
25
|
-
name: json
|
|
26
21
|
prerelease: false
|
|
27
|
-
|
|
28
|
-
requirements:
|
|
29
|
-
- -
|
|
30
|
-
- !ruby/object:Gem::Version
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - ~>
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '2.3'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: json
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - '>='
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
31
33
|
version: 1.5.1
|
|
32
34
|
type: :runtime
|
|
33
|
-
version_requirements: *id002
|
|
34
|
-
- !ruby/object:Gem::Dependency
|
|
35
|
-
name: travis
|
|
36
35
|
prerelease: false
|
|
37
|
-
|
|
38
|
-
requirements:
|
|
39
|
-
-
|
|
40
|
-
-
|
|
41
|
-
|
|
42
|
-
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - '>='
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: 1.5.1
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: travis
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - '>='
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '0'
|
|
43
48
|
type: :development
|
|
44
|
-
version_requirements: *id003
|
|
45
|
-
- !ruby/object:Gem::Dependency
|
|
46
|
-
name: rake
|
|
47
49
|
prerelease: false
|
|
48
|
-
|
|
49
|
-
requirements:
|
|
50
|
-
-
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - '>='
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '0'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - '>='
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '0'
|
|
51
62
|
type: :development
|
|
52
|
-
version_requirements: *id005
|
|
53
|
-
- !ruby/object:Gem::Dependency
|
|
54
|
-
name: rdoc
|
|
55
63
|
prerelease: false
|
|
56
|
-
|
|
57
|
-
requirements:
|
|
58
|
-
-
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - '>='
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: rdoc
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - '>='
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '0'
|
|
59
76
|
type: :development
|
|
60
|
-
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - '>='
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '0'
|
|
61
83
|
description: A simple Ruby client for the algolia.com REST API
|
|
62
84
|
email: contact@algolia.com
|
|
63
85
|
executables: []
|
|
64
|
-
|
|
65
86
|
extensions: []
|
|
66
|
-
|
|
67
|
-
extra_rdoc_files:
|
|
87
|
+
extra_rdoc_files:
|
|
68
88
|
- ChangeLog
|
|
69
89
|
- LICENSE.txt
|
|
70
90
|
- README.md
|
|
71
|
-
files:
|
|
91
|
+
files:
|
|
72
92
|
- .rspec
|
|
73
93
|
- .travis.yml
|
|
74
94
|
- ChangeLog
|
|
@@ -92,27 +112,27 @@ files:
|
|
|
92
112
|
- spec/spec_helper.rb
|
|
93
113
|
- spec/stub_spec.rb
|
|
94
114
|
homepage: http://github.com/algolia/algoliasearch-client-ruby
|
|
95
|
-
licenses:
|
|
115
|
+
licenses:
|
|
96
116
|
- MIT
|
|
97
117
|
metadata: {}
|
|
98
|
-
|
|
99
118
|
post_install_message:
|
|
100
119
|
rdoc_options: []
|
|
101
|
-
|
|
102
|
-
require_paths:
|
|
120
|
+
require_paths:
|
|
103
121
|
- lib
|
|
104
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
|
105
|
-
requirements:
|
|
106
|
-
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
122
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
123
|
+
requirements:
|
|
124
|
+
- - '>='
|
|
125
|
+
- !ruby/object:Gem::Version
|
|
126
|
+
version: '0'
|
|
127
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - '>='
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '0'
|
|
110
132
|
requirements: []
|
|
111
|
-
|
|
112
133
|
rubyforge_project:
|
|
113
|
-
rubygems_version: 2.
|
|
134
|
+
rubygems_version: 2.1.11
|
|
114
135
|
signing_key:
|
|
115
136
|
specification_version: 4
|
|
116
137
|
summary: A simple Ruby client for the algolia.com REST API
|
|
117
138
|
test_files: []
|
|
118
|
-
|