algoliasearch 1.6.1 → 1.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/ChangeLog +3 -0
- data/README.md +97 -62
- data/lib/algolia/client.rb +17 -5
- data/lib/algolia/version.rb +1 -1
- data/spec/client_spec.rb +13 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 09439a03773ded1c14b3085d75beca0fcd8ad5ea
|
4
|
+
data.tar.gz: 0afd459775b461e96b952540f2889a54c7b8a9c6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b1cb21a4b0382bf44a5319d4060a816300c53a14c43db82b5e21b89a607650b6f9bbc3e0bf02c5227c2e20488333593d630e4ac5834c0f4a520c346c5aa0c14a
|
7
|
+
data.tar.gz: 65e765e1557b807f380f010c1ac2548a804e9fae494003dbb8b151bc187dd4ff9bfddff3628d8828be756ea49893b003ce5cb1b4cdee0cb91e95747f526694c3
|
data/ChangeLog
CHANGED
data/README.md
CHANGED
@@ -3,11 +3,14 @@
|
|
3
3
|
|
4
4
|
|
5
5
|
|
6
|
+
|
6
7
|
[Algolia Search](http://www.algolia.com) is a hosted full-text, numerical, and faceted search engine capable of delivering realtime results from the first keystroke.
|
7
8
|
|
8
9
|
Our Ruby client lets you easily use the [Algolia Search API](https://www.algolia.com/doc/rest_api) from your backend. It wraps the [Algolia Search REST API](http://www.algolia.com/doc/rest_api).
|
9
10
|
|
10
11
|
|
12
|
+
|
13
|
+
|
11
14
|
[![Build Status](https://travis-ci.org/algolia/algoliasearch-client-ruby.svg?branch=master)](https://travis-ci.org/algolia/algoliasearch-client-ruby) [![Gem Version](https://badge.fury.io/rb/algoliasearch.svg)](http://badge.fury.io/rb/algoliasearch) [![Code Climate](https://codeclimate.com/github/algolia/algoliasearch-client-ruby.svg)](https://codeclimate.com/github/algolia/algoliasearch-client-ruby) [![Coverage Status](https://coveralls.io/repos/algolia/algoliasearch-client-ruby/badge.png)](https://coveralls.io/r/algolia/algoliasearch-client-ruby)
|
12
15
|
|
13
16
|
|
@@ -22,6 +25,7 @@ Table of Contents
|
|
22
25
|
1. [Online documentation](#documentation)
|
23
26
|
1. [Tutorials](#tutorials)
|
24
27
|
|
28
|
+
|
25
29
|
**Commands Reference**
|
26
30
|
|
27
31
|
1. [Add a new object](#add-a-new-object-to-the-index)
|
@@ -51,7 +55,6 @@ To setup your project, follow these steps:
|
|
51
55
|
|
52
56
|
|
53
57
|
|
54
|
-
|
55
58
|
1. Install AlgoliaSearch using <code>gem install algoliasearch</code>.
|
56
59
|
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).
|
57
60
|
|
@@ -173,6 +176,7 @@ Check out our [tutorials](http://www.algolia.com/doc/tutorials):
|
|
173
176
|
|
174
177
|
|
175
178
|
|
179
|
+
|
176
180
|
Commands Reference
|
177
181
|
==================
|
178
182
|
|
@@ -226,9 +230,9 @@ index.save_object({"firstname" => "Jimmie",
|
|
226
230
|
You have many ways to update an object's attributes:
|
227
231
|
|
228
232
|
1. Set the attribute value
|
229
|
-
2. Add
|
233
|
+
2. Add a string or number element to an array
|
230
234
|
3. Remove an element from an array
|
231
|
-
4. Add
|
235
|
+
4. Add a string or number element to an array if it doesn't exist
|
232
236
|
5. Increment an attribute
|
233
237
|
6. Decrement an attribute
|
234
238
|
|
@@ -242,38 +246,44 @@ index.partial_update_object({"city" => "San Francisco",
|
|
242
246
|
Example to add a tag:
|
243
247
|
|
244
248
|
```ruby
|
245
|
-
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation"
|
249
|
+
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation" => "Add"},
|
246
250
|
"objectID" => "myID"})
|
247
251
|
```
|
248
252
|
|
249
253
|
Example to remove a tag:
|
250
254
|
|
251
255
|
```ruby
|
252
|
-
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation"
|
256
|
+
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation" => "Remove"},
|
253
257
|
"objectID" => "myID"})
|
254
258
|
```
|
255
259
|
|
256
260
|
Example to add a tag if it doesn't exist:
|
257
261
|
|
258
262
|
```ruby
|
259
|
-
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation"
|
263
|
+
index.partial_update_object({"_tags" => {"value" => "MyTag", "_operation" => "AddUnique"},
|
260
264
|
"objectID" => "myID"})
|
261
265
|
```
|
262
266
|
|
263
267
|
Example to increment a numeric value:
|
264
268
|
|
265
269
|
```ruby
|
266
|
-
index.partial_update_object({"price" => {"value" => 42, "_operation"
|
270
|
+
index.partial_update_object({"price" => {"value" => 42, "_operation" => "Increment"},
|
267
271
|
"objectID" => "myID"})
|
268
272
|
```
|
269
273
|
|
274
|
+
Note: Here we are incrementing the value by `42`. To increment just by one, put
|
275
|
+
`value:1`.
|
276
|
+
|
270
277
|
Example to decrement a numeric value:
|
271
278
|
|
272
279
|
```ruby
|
273
|
-
index.partial_update_object({"price" => {"value" => 42, "_operation"
|
280
|
+
index.partial_update_object({"price" => {"value" => 42, "_operation" => "Decrement"},
|
274
281
|
"objectID" => "myID"})
|
275
282
|
```
|
276
283
|
|
284
|
+
Note: Here we are decrementing the value by `42`. To decrement just by one, put
|
285
|
+
`value:1`.
|
286
|
+
|
277
287
|
Search
|
278
288
|
-------------
|
279
289
|
|
@@ -284,6 +294,8 @@ Search
|
|
284
294
|
|
285
295
|
To perform a search, you only need to initialize the index and perform a call to the search function.
|
286
296
|
|
297
|
+
The search query allows only to retrieve 1000 hits, if you need to retrieve more than 1000 hits for seo, you can use [Backup / Retrieve all index content](#backup--retrieve-of-all-index-content)
|
298
|
+
|
287
299
|
You can use the following optional arguments:
|
288
300
|
|
289
301
|
### Query Parameters
|
@@ -298,7 +310,7 @@ You can use the following optional arguments:
|
|
298
310
|
* **removeWordsIfNoResults**: This option is used to select a strategy in order to avoid having an empty result page. There are three different options:
|
299
311
|
* **lastWords**: When a query does not return any results, the last word will be added as optional. The process is repeated with n-1 word, n-2 word, ... until there are results.
|
300
312
|
* **firstWords**: When a query does not return any results, the first word will be added as optional. The process is repeated with second word, third word, ... until there are results.
|
301
|
-
* **allOptional**: When a query does not return any results, a second trial will be made with all words as optional. This is equivalent to transforming the AND operand between query terms to an OR operand.
|
313
|
+
* **allOptional**: When a query does not return any results, a second trial will be made with all words as optional. This is equivalent to transforming the AND operand between query terms to an OR operand.
|
302
314
|
* **none**: No specific processing is done when a query does not return any results (default behavior).
|
303
315
|
* **minWordSizefor1Typo**: The minimum number of characters in a query word to accept one typo in this word.<br/>Defaults to 4.
|
304
316
|
* **minWordSizefor2Typos**: The minimum number of characters in a query word to accept two typos in this word.<br/>Defaults to 8.
|
@@ -310,7 +322,9 @@ You can use the following optional arguments:
|
|
310
322
|
* **strict**: Hits matching with 2 typos are not retrieved if there are some matching without typos. This option is useful if you want to avoid false positives as much as possible.
|
311
323
|
* **allowTyposOnNumericTokens**: If set to false, disables typo tolerance on numeric tokens (numbers). Defaults to true.
|
312
324
|
* **ignorePlural**: If set to true, plural won't be considered as a typo. For example, car and cars will be considered as equals. Defaults to false.
|
325
|
+
* **disableTypoToleranceOnAttributes** List of attributes on which you want to disable typo tolerance (must be a subset of the `attributesToIndex` index setting). Attributes are separated with a comma such as `"name,address"`. You can also use JSON string array encoding such as `encodeURIComponent("[\"name\",\"address\"]")`. By default, this list is empty.
|
313
326
|
* **restrictSearchableAttributes** List of attributes you want to use for textual search (must be a subset of the `attributesToIndex` index setting). Attributes are separated with a comma such as `"name,address"`. You can also use JSON string array encoding such as `encodeURIComponent("[\"name\",\"address\"]")`. By default, all attributes specified in `attributesToIndex` settings are used to search.
|
327
|
+
* **removeStopWords**: Remove stop words from query before executing it. Defaults to false. Contains stop words for 41 languages (Arabic, Armenian, Basque, Bengali, Brazilian, Bulgarian, Catalan, Chinese, Czech, Danish, Dutch, English, Finnish, French, Galician, German, Greek, Hindi, Hungarian, Indonesian, Irish, Italian, Japanese, Korean, Kurdish, Latvian, Lithuanian, Marathi, Norwegian, Persian, Polish, Portugese, Romanian, Russian, Slovak, Spanish, Swedish, Thai, Turkish, Ukranian, Urdu).
|
314
328
|
* **advancedSyntax**: Enables the advanced query syntax. Defaults to 0 (false).
|
315
329
|
* **Phrase query**: A phrase query defines a particular sequence of terms. A phrase query is built by Algolia's query parser for words surrounded by `"`. For example, `"search engine"` will retrieve records having `search` next to `engine` only. Typo tolerance is _disabled_ on phrase queries.
|
316
330
|
* **Prohibit operator**: The prohibit operator excludes records that contain the term after the `-` symbol. For example, `search -engine` will retrieve records containing `search` but not `engine`.
|
@@ -326,12 +340,12 @@ You can use the following optional arguments:
|
|
326
340
|
|
327
341
|
#### Geo-search Parameters
|
328
342
|
|
329
|
-
* **aroundLatLng**: Search for entries around a given latitude/longitude (specified as two floats separated by a comma).<br/>For example, `aroundLatLng=47.316669,5.016670`.<br/>
|
330
|
-
|
331
|
-
* **aroundLatLngViaIP**: Search for entries around a given latitude/longitude automatically computed from user IP address.<br/>For example, `aroundLatLng=47.316669,5.016670`.<br/>You can specify the maximum distance in meters with the **aroundRadius** parameter and the precision for ranking with **aroundPrecision**. For example, if you set aroundPrecision=100, two objects that are a distance of less than 100 meters will be considered as identical for the "geo" ranking parameter.<br/>At indexing, you should specify the geo location of an object with the `_geoloc` attribute in the form `{"_geoloc":{"lat":48.853409, "lng":2.348800}}`.
|
343
|
+
* **aroundLatLng**: Search for entries around a given latitude/longitude (specified as two floats separated by a comma).<br/>For example, `aroundLatLng=47.316669,5.016670`.<br/>By default the maximum distance is automatically guessed based on the density of the area but you can specify it manually in meters with the **aroundRadius** parameter. The precision for ranking can be set with **aroundPrecision** parameter. For example, if you set aroundPrecision=100, the distances will be considered by ranges of 100m, for example all distances 0 and 100m will be considered as identical for the "geo" ranking parameter.<br/>When **aroundRadius** is not set, the radius is computed automatically using the density of the area, you can retrieve the computed radius in the **automaticRadius** attribute of the answer, you can also use the **minimumAroundRadius** query parameter to specify a minimum radius in meters for the automatic computation of **aroundRadius**.<br/>At indexing, you should specify geoloc of an object with the _geoloc attribute (in the form `"_geoloc":{"lat":48.853409, "lng":2.348800}` or `"_geoloc":[{"lat":48.853409, "lng":2.348800},{"lat":48.547456, "lng":2.972075}]` if you have several geo-locations in your record).
|
332
344
|
|
345
|
+
* **aroundLatLngViaIP**: Search for entries around a given latitude/longitude automatically computed from user IP address.<br/>For example, `aroundLatLng=47.316669,5.016670`.<br/>You can specify the maximum distance in meters with the **aroundRadius** parameter and the precision for ranking with **aroundPrecision**. For example, if you set aroundPrecision=100, two objects that are in the range 0-99m will be considered as identic in the ranking for the "geo" ranking parameter (same for 100-199, 200-299, ... ranges).<br/>At indexing, you should specify the geo location of an object with the `_geoloc` attribute in the form `{"_geoloc":{"lat":48.853409, "lng":2.348800}}`.
|
333
346
|
|
334
|
-
* **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
|
347
|
+
* **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}` or `"_geoloc":[{"lat":48.853409, "lng":2.348800},{"lat":48.547456, "lng":2.972075}]` if you have several geo-locations in your record). You can use several bounding boxes (OR) by passing more than 4 values. For example instead of having 4 values you can pass 8 to use or OR between two bounding boxes.
|
348
|
+
* **insidePolygon**: Search entries inside a given area defined by a set of points (defined by a minimum of 6 floats: p1Lat,p1Lng,p2Lat,p2Lng,p3Lat,p3Long).<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}` or `"_geoloc":[{"lat":48.853409, "lng":2.348800},{"lat":48.547456, "lng":2.972075}]` if you have several geo-locations in your record).
|
335
349
|
|
336
350
|
#### Parameters to Control Results Content
|
337
351
|
|
@@ -342,6 +356,8 @@ You can use the following optional arguments:
|
|
342
356
|
* **none**: If none of the query terms were found.
|
343
357
|
* **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 commas (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.
|
344
358
|
* **getRankingInfo**: If set to 1, the result hits will contain ranking information in the **_rankingInfo** attribute.
|
359
|
+
* **highlightPreTag**: (string) Specify the string that is inserted before the highlighted parts in the query result (defaults to "<em>").
|
360
|
+
* **highlightPostTag**: (string) Specify the string that is inserted after the highlighted parts in the query result (defaults to "</em>").
|
345
361
|
|
346
362
|
|
347
363
|
#### Numeric Search Parameters
|
@@ -358,12 +374,29 @@ You can also use a string array encoding (for example `numericFilters: ["price>1
|
|
358
374
|
|
359
375
|
#### Faceting Parameters
|
360
376
|
* **facetFilters**: Filter the query with a list of facets. Facets are separated by commas and 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"]`.
|
361
|
-
* **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 JSON string array encoding. For example, `["category","author"]`. Only the 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**.
|
377
|
+
* **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 JSON string array encoding. For example, `["category","author"]`. Only the 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**. If the number of results is important, the count can be approximate, the attribute `exhaustiveFacetsCount` in the response is true when the count is exact.
|
362
378
|
* **maxValuesPerFacet**: Limit the number of facet values returned for each facet. For example, `maxValuesPerFacet=10` will retrieve a maximum of 10 values per facet.
|
363
379
|
|
380
|
+
#### UNIFIED FILTER PARAMETER (SQL LIKE)
|
381
|
+
* **filters**: Filter the query with numeric, facet or/and tag filters. The syntax is a SQL like syntax, you can use the OR and AND keywords. The syntax for the underlying numeric, facet and tag filters is the same than in the other filters:
|
382
|
+
`available=1 AND (category:Book OR NOT category:Ebook) AND public`
|
383
|
+
`date: 1441745506 TO 1441755506 AND inStock > 0 AND author:"John Doe"`
|
384
|
+
The list of keywords is:
|
385
|
+
**OR**: create a disjunctive filter between two filters.
|
386
|
+
**AND**: create a conjunctive filter between two filters.
|
387
|
+
**TO**: used to specify a range for a numeric filter.
|
388
|
+
**NOT**: used to negate a filter. The syntax with the ‘-‘ isn’t allowed.
|
389
|
+
|
390
|
+
*Note*: To specify a value with spaces or with a value equal to a keyword, it's possible to add quotes.
|
391
|
+
|
392
|
+
**Warning:**
|
393
|
+
* Like for the other filter for performance reason, it's not possible to have FILTER1 OR (FILTER2 AND FILTER3).
|
394
|
+
* It's not possible to mix different category of filter inside a OR like num=3 OR tag1 OR facet:value
|
395
|
+
* It's not possible to negate an group, it's only possible to negate a filters: NOT(FILTER1 OR (FILTER2) is not allowed.
|
396
|
+
|
397
|
+
|
364
398
|
#### Distinct Parameter
|
365
399
|
* **distinct**: If set to 1, enables the distinct feature, disabled by default, if the `attributeForDistinct` index setting is set. This feature is similar to the SQL "distinct" keyword. When enabled in a query with the `distinct=1` parameter, all hits containing a duplicate value for the attributeForDistinct attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and the others are removed.
|
366
|
-
**Note**: This feature is disabled if the query string is empty and there aren't any `tagFilters`, `facetFilters`, nor `numericFilters` parameters.
|
367
400
|
|
368
401
|
```ruby
|
369
402
|
index = Algolia::Index.new("contacts")
|
@@ -407,6 +440,9 @@ The server response will look like:
|
|
407
440
|
```
|
408
441
|
|
409
442
|
|
443
|
+
|
444
|
+
|
445
|
+
|
410
446
|
Multiple queries
|
411
447
|
--------------
|
412
448
|
|
@@ -485,7 +521,7 @@ You can retrieve all settings using the `get_settings` function. The result will
|
|
485
521
|
You can decide to have the same priority for two attributes by passing them in the same string using a comma as a separator. For example `title` and `alternative_title` have the same priority in this example, which is different than text priority: `attributesToIndex:["title,alternative_title", "text"]`.
|
486
522
|
* **numericAttributesToIndex**: (array of strings) All numerical attributes are automatically indexed as numerical filters. If you don't need filtering on some of your numerical attributes, you can specify this list to speed up the indexing.<br/> If you only need to filter on a numeric value with the operator '=', you can speed up the indexing by specifying the attribute with `equalOnly(AttributeName)`. The other operators will be disabled.
|
487
523
|
* **attributesForFaceting**: (array of strings) The list of fields you want to use for faceting. All strings in the attribute selected for faceting are extracted and added as a facet. If set to null, no attribute is used for faceting.
|
488
|
-
* **attributeForDistinct**: The attribute name used for the `Distinct` feature. This feature is similar to the SQL "distinct" keyword. When enabled in queries with the `distinct=1` parameter, all hits containing a duplicate value for this attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and others are removed.
|
524
|
+
* **attributeForDistinct**: The attribute name used for the `Distinct` feature. This feature is similar to the SQL "distinct" keyword. When enabled in queries with the `distinct=1` parameter, all hits containing a duplicate value for this attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and others are removed.
|
489
525
|
* **ranking**: (array of strings) Controls the way results are sorted.<br/>We have nine available criteria:
|
490
526
|
* **typo**: Sort according to number of typos.
|
491
527
|
* **geo**: Sort according to decreasing distance when performing a geo location based search.
|
@@ -513,7 +549,8 @@ You can decide to have the same priority for two attributes by passing them in t
|
|
513
549
|
* **placeholders**: (hash of array of words). This is an advanced use case to define a token substitutable by a list of words without having the original token searchable. It is defined by a hash associating placeholders to lists of substitutable words. For example, `"placeholders": { "<streetnumber>": ["1", "2", "3", ..., "9999"]}` would allow it to be able to match all street numbers. We use the `< >` tag syntax to define placeholders in an attribute. For example:
|
514
550
|
* Push a record with the placeholder: `{ "name" : "Apple Store", "address" : "<streetnumber> Opera street, Paris" }`.
|
515
551
|
* Configure the placeholder in your index settings: `"placeholders": { "<streetnumber>" : ["1", "2", "3", "4", "5", ... ], ... }`.
|
516
|
-
* **
|
552
|
+
* **disableTypoToleranceOnWords**: (string array) Specify a list of words on which automatic typo tolerance will be disabled.
|
553
|
+
* **disableTypoToleranceOnAttributes**: (string array) List of attributes on which you want to disable typo tolerance (must be a subset of the `attributesToIndex` index setting). By default the list is empty.
|
517
554
|
* **altCorrections**: (object array) Specify alternative corrections that you want to consider. Each alternative correction is described by an object containing three attributes:
|
518
555
|
* **word**: The word to correct.
|
519
556
|
* **correction**: The corrected word.
|
@@ -531,6 +568,26 @@ You can decide to have the same priority for two attributes by passing them in t
|
|
531
568
|
* **highlightPreTag**: (string) Specify the string that is inserted before the highlighted parts in the query result (defaults to "<em>").
|
532
569
|
* **highlightPostTag**: (string) Specify the string that is inserted after the highlighted parts in the query result (defaults to "</em>").
|
533
570
|
* **optionalWords**: (array of strings) Specify a list of words that should be considered optional when found in the query.
|
571
|
+
* **allowTyposOnNumericTokens**: (boolean) If set to false, disable typo-tolerance on numeric tokens (=numbers) in the query word. For example the query `"304"` will match with `"30450"`, but not with `"40450"` that would have been the case with typo-tolerance enabled. Can be very useful on serial numbers and zip codes searches. Default to false.
|
572
|
+
* **ignorePlurals**: (boolean) If set to true, simple plural forms won’t be considered as typos (for example car/cars will be considered as equal). Default to false.
|
573
|
+
* **advancedSyntax**: Enable the advanced query syntax. Defaults to 0 (false).
|
574
|
+
|
575
|
+
* **Phrase query:** a phrase query defines a particular sequence of terms. A phrase query is build by Algolia's query parser for words surrounded by `"`. For example, `"search engine"` will retrieve records having `search` next to `engine` only. Typo-tolerance is disabled on phrase queries.
|
576
|
+
|
577
|
+
* **Prohibit operator:** The prohibit operator excludes records that contain the term after the `-` symbol. For example `search -engine` will retrieve records containing `search` but not `engine`.
|
578
|
+
* **replaceSynonymsInHighlight**: (boolean) If set to false, words matched via synonyms expansion will not be replaced by the matched synonym in the highlighted result. Default to true.
|
579
|
+
* **maxValuesPerFacet**: (integer) Limit the number of facet values returned for each facet. For example: `maxValuesPerFacet=10` will retrieve max 10 values per facet.
|
580
|
+
* **distinct**: (integer) Enable the distinct feature (disabled by default) if the `attributeForDistinct` index setting is set. This feature is similar to the SQL "distinct" keyword: when enabled in a query with the `distinct=1` parameter, all hits containing a duplicate value for the`attributeForDistinct` attribute are removed from results. For example, if the chosen attribute is `show_name` and several hits have the same value for `show_name`, then only the best one is kept and others are removed.
|
581
|
+
* **typoTolerance**: (string) This setting has four different options:
|
582
|
+
|
583
|
+
* **true:** activate the typo-tolerance (default value).
|
584
|
+
|
585
|
+
* **false:** disable the typo-tolerance
|
586
|
+
|
587
|
+
* **min:** keep only results with the lowest number of typo. For example if one result match without typos, then all results with typos will be hidden.
|
588
|
+
|
589
|
+
* **strict:** if there is a match without typo, then all results with 2 typos or more will be removed. This option is useful if you want to avoid as much as possible false positive.
|
590
|
+
* **removeStopWords**: (boolean) Remove stop words from query before executing it. Defaults to false. Contains stop words for 41 languages (Arabic, Armenian, Basque, Bengali, Brazilian, Bulgarian, Catalan, Chinese, Czech, Danish, Dutch, English, Finnish, French, Galician, German, Greek, Hindi, Hungarian, Indonesian, Irish, Italian, Japanese, Korean, Kurdish, Latvian, Lithuanian, Marathi, Norwegian, Persian, Polish, Portugese, Romanian, Russian, Slovak, Spanish, Swedish, Thai, Turkish, Ukranian, Urdu)
|
534
591
|
|
535
592
|
You can easily retrieve settings or update them:
|
536
593
|
|
@@ -594,7 +651,7 @@ Batch writes
|
|
594
651
|
-------------
|
595
652
|
|
596
653
|
You may want to perform multiple operations with one API call to reduce latency.
|
597
|
-
We expose
|
654
|
+
We expose four methods to perform batch operations:
|
598
655
|
* `add_objects`: Add an array of objects using automatic `objectID` assignment.
|
599
656
|
* `save_objects`: Add or update an array of objects that contains an `objectID` attribute.
|
600
657
|
* `delete_objects`: Delete an array of objectIDs.
|
@@ -688,17 +745,17 @@ puts res['key']
|
|
688
745
|
|
689
746
|
You can also create an API Key with advanced settings:
|
690
747
|
|
691
|
-
* Add a validity period. The key will be valid for a specific period of time (in seconds).
|
692
|
-
* Specify the maximum number of API calls allowed from an IP address per hour. Each time an API call is performed with this key, a check is performed. If the IP at the source of the call did more than this number of calls in the last hour, a 403 code is returned. Defaults to 0 (no rate limit). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
|
748
|
+
* **validity**: Add a validity period. The key will be valid for a specific period of time (in seconds).
|
749
|
+
* **maxQueriesPerIPPerHour**: Specify the maximum number of API calls allowed from an IP address per hour. Each time an API call is performed with this key, a check is performed. If the IP at the source of the call did more than this number of calls in the last hour, a 403 code is returned. Defaults to 0 (no rate limit). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
|
693
750
|
|
694
751
|
|
695
752
|
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.
|
696
753
|
|
697
|
-
* Specify the maximum number of hits this API key can retrieve in one call. Defaults to 0 (unlimited). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
|
698
|
-
* Specify the list of targeted indices. You can target all indices starting with a prefix or ending with a suffix using the '
|
699
|
-
* Specify the list of referers. You can target all referers starting with a prefix or ending with a suffix using the '
|
700
|
-
* Specify the list of query parameters. You can force the query parameters for a query using the url string format (param1=X¶m2=Y...).
|
701
|
-
* Specify a description to describe where the key is used.
|
754
|
+
* **maxHitsPerQuery**: Specify the maximum number of hits this API key can retrieve in one call. Defaults to 0 (unlimited). This parameter can be used to protect you from attempts at retrieving your entire index contents by massively querying the index.
|
755
|
+
* **indexes**: Specify the list of targeted indices. You can target all indices starting with a prefix or ending with a suffix using the '\*' character. For example, "dev\_\*" matches all indices starting with "dev\_" and "\*\_dev" matches all indices ending with "\_dev". Defaults to all indices if empty or blank.
|
756
|
+
* **referers**: Specify the list of referers. You can target all referers starting with a prefix or ending with a suffix using the '\*' character. For example, "algolia.com/\*" matches all referers starting with "algolia.com/" and "\*.algolia.com" matches all referers ending with ".algolia.com". Defaults to all referers if empty or blank.
|
757
|
+
* **queryParameters**: Specify the list of query parameters. You can force the query parameters for a query using the url string format (param1=X¶m2=Y...).
|
758
|
+
* **description**: Specify a description to describe where the key is used.
|
702
759
|
|
703
760
|
|
704
761
|
```ruby
|
@@ -761,14 +818,13 @@ You may have a single index containing per user data. In that case, all records
|
|
761
818
|
```ruby
|
762
819
|
# generate a public API key for user 42. Here, records are tagged with:
|
763
820
|
# - 'user_XXXX' if they are visible by user XXXX
|
764
|
-
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', 'tagFilters
|
821
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'tagFilters'=> 'user_42'}
|
765
822
|
```
|
766
823
|
|
767
824
|
This public API key can then be used in your JavaScript code as follow:
|
768
825
|
|
769
826
|
```js
|
770
827
|
var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
|
771
|
-
client.setExtraHeader('X-Algolia-QueryParameters', 'tagFilters=user_42'); // must be same than those used at generation-time
|
772
828
|
|
773
829
|
var index = client.initIndex('indexName')
|
774
830
|
|
@@ -782,12 +838,12 @@ index.search('something', function(err, content) {
|
|
782
838
|
});
|
783
839
|
```
|
784
840
|
|
785
|
-
You can mix rate limits and secured API keys by setting
|
841
|
+
You can mix rate limits and secured API keys by setting a `userToken` query parameter at API key generation time. When set, a unique user will be identified by her `IP + user_token` instead of only by her `IP`. This allows you to restrict a single user to performing a maximum of `N` API calls per hour, even if she shares her `IP` with another user.
|
786
842
|
|
787
843
|
```ruby
|
788
844
|
# generate a public API key for user 42. Here, records are tagged with:
|
789
845
|
# - 'user_XXXX' if they are visible by user XXXX
|
790
|
-
public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', 'tagFilters
|
846
|
+
public_key = Algolia.generate_secured_api_key 'YourRateLimitedApiKey', {'tagFilters'=> 'user_42', 'userToken'=> 'user_42'}
|
791
847
|
```
|
792
848
|
|
793
849
|
This public API key can then be used in your JavaScript code as follow:
|
@@ -795,32 +851,6 @@ This public API key can then be used in your JavaScript code as follow:
|
|
795
851
|
```js
|
796
852
|
var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
|
797
853
|
|
798
|
-
// must be same than those used at generation-time
|
799
|
-
client.setExtraHeader('X-Algolia-QueryParameters', 'tagFilters=user_42');
|
800
|
-
|
801
|
-
// must be same than the one used at generation-time
|
802
|
-
client.setUserToken('user_42');
|
803
|
-
|
804
|
-
var index = client.initIndex('indexName')
|
805
|
-
|
806
|
-
index.search('another query', function(err, content) {
|
807
|
-
if (err) {
|
808
|
-
console.error(err);
|
809
|
-
return;
|
810
|
-
}
|
811
|
-
|
812
|
-
console.log(content);
|
813
|
-
});
|
814
|
-
```
|
815
|
-
|
816
|
-
You can also generate secured API keys to limit the usage of a key to a referer. The generation use the same function than the Per user restriction. This public API key can be used in your JavaScript code as follow:
|
817
|
-
|
818
|
-
```js
|
819
|
-
var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
|
820
|
-
|
821
|
-
// must be same than those used at generation-time
|
822
|
-
client.setExtraHeader('X-Algolia-AllowedReferer', 'algolia.com/*');
|
823
|
-
|
824
854
|
var index = client.initIndex('indexName')
|
825
855
|
|
826
856
|
index.search('another query', function(err, content) {
|
@@ -834,7 +864,6 @@ index.search('another query', function(err, content) {
|
|
834
864
|
```
|
835
865
|
|
836
866
|
|
837
|
-
|
838
867
|
Copy or rename an index
|
839
868
|
-------------
|
840
869
|
|
@@ -857,19 +886,25 @@ The move command is particularly useful if you want to update a big index atomic
|
|
857
886
|
puts Algolia.move_index("MyNewIndex", "MyIndex")
|
858
887
|
```
|
859
888
|
|
889
|
+
|
860
890
|
Backup / Retrieve of all index content
|
861
891
|
-------------
|
862
892
|
|
863
893
|
You can retrieve all index content for backup purposes or for SEO using the browse method.
|
864
|
-
This method
|
894
|
+
This method can retrieve up to 1,000 objects per call and supports full text search and filters but the distinct feature is not available
|
895
|
+
Unlike the search method, the sort by typo, proximity, geo distance and matched words is not applied, the hits are only sorted by numeric attributes specified in the ranking and the custom ranking.
|
896
|
+
|
897
|
+
You can browse the index:
|
865
898
|
|
866
899
|
```ruby
|
867
|
-
#
|
868
|
-
|
869
|
-
#
|
870
|
-
|
900
|
+
# Iterate with a filter over the index
|
901
|
+
index.browse({:query => "test", :numericFilters => 'i=42'}) do
|
902
|
+
# Do something
|
903
|
+
end
|
871
904
|
```
|
872
905
|
|
906
|
+
|
907
|
+
|
873
908
|
Logs
|
874
909
|
-------------
|
875
910
|
|
@@ -919,7 +954,7 @@ describe 'With a mocked client' do
|
|
919
954
|
it "shouldn't perform any API calls here" do
|
920
955
|
index = Algolia::Index.new("friends")
|
921
956
|
index.add_object!({ :name => "John Doe", :email => "john@doe.org" })
|
922
|
-
index.search('').should == {} # mocked
|
957
|
+
index.search('').should == {"hits"=>[{"objectID"=>42}], "page"=>1, "hitsPerPage"=>1} # mocked
|
923
958
|
index.clear_index
|
924
959
|
index.delete_index
|
925
960
|
end
|
data/lib/algolia/client.rb
CHANGED
@@ -4,6 +4,7 @@ require 'algolia/version'
|
|
4
4
|
require 'json'
|
5
5
|
require 'zlib'
|
6
6
|
require 'openssl'
|
7
|
+
require 'base64'
|
7
8
|
|
8
9
|
module Algolia
|
9
10
|
|
@@ -98,7 +99,9 @@ module Algolia
|
|
98
99
|
def multiple_queries(queries, index_name_key = :index_name, strategy = "none")
|
99
100
|
requests = {
|
100
101
|
:requests => queries.map do |query|
|
102
|
+
query = query.dup
|
101
103
|
indexName = query.delete(index_name_key) || query.delete(index_name_key.to_s)
|
104
|
+
raise ArgumentError.new("Missing '#{index_name_key}' option") if indexName.nil?
|
102
105
|
encoded_params = Hash[query.map { |k,v| [k.to_s, v.is_a?(Array) ? v.to_json : v] }]
|
103
106
|
{ :indexName => indexName, :params => Protocol.to_query(encoded_params) }
|
104
107
|
end
|
@@ -469,12 +472,21 @@ module Algolia
|
|
469
472
|
# @param tag_filters the list of tags applied to the query (used as security)
|
470
473
|
# @param user_token an optional token identifying the current user
|
471
474
|
#
|
472
|
-
def Algolia.generate_secured_api_key(private_api_key,
|
473
|
-
if
|
474
|
-
|
475
|
+
def Algolia.generate_secured_api_key(private_api_key, tag_filters_or_params, user_token = nil)
|
476
|
+
if tag_filters_or_params.is_a?(Hash) && user_token.nil?
|
477
|
+
encoded_params = Hash[tag_filters_or_params.map { |k,v| [k.to_s, v.is_a?(Array) ? v.to_json : v] }]
|
478
|
+
query_str = Protocol.to_query(encoded_params)
|
479
|
+
hmac = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), private_api_key, query_str)
|
480
|
+
Base64.encode64("#{hmac}#{query_str}").gsub("\n", '')
|
481
|
+
else
|
482
|
+
tag_filters = if tag_filters_or_params.is_a?(Array)
|
483
|
+
tag_filters = tag_filters_or_params.map { |t| t.is_a?(Array) ? "(#{t.join(',')})" : t }.join(',')
|
484
|
+
else
|
485
|
+
tag_filters_or_params
|
486
|
+
end
|
487
|
+
raise ArgumentError.new('Attribute "tag_filters" must be a list of tags') if !tag_filters.is_a?(String)
|
488
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), private_api_key, "#{tag_filters}#{user_token.to_s}")
|
475
489
|
end
|
476
|
-
raise ArgumentError.new('Attribute "tag_filters" must be a list of tags') if !tag_filters.is_a?(String)
|
477
|
-
OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), private_api_key, "#{tag_filters}#{user_token.to_s}")
|
478
490
|
end
|
479
491
|
|
480
492
|
#
|
data/lib/algolia/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), 'spec_helper'))
|
3
|
+
require 'base64'
|
3
4
|
|
4
5
|
# avoid concurrent access to the same index
|
5
6
|
def safe_index_name(name)
|
@@ -277,6 +278,10 @@ describe 'Client' do
|
|
277
278
|
res["results"][0]["hits"].length.should eq(1)
|
278
279
|
end
|
279
280
|
|
281
|
+
it "should throw if the index_name is missing in multiple_queries" do
|
282
|
+
expect { Algolia.multiple_queries([{"query" => ""}]) }.to raise_error(ArgumentError)
|
283
|
+
end
|
284
|
+
|
280
285
|
it "shoud accept custom batch" do
|
281
286
|
@index.clear_index! rescue "Not fatal"
|
282
287
|
request = { "requests" => [
|
@@ -647,7 +652,7 @@ describe 'Client' do
|
|
647
652
|
logs['logs'][0]['sha1'].should be_a(String)
|
648
653
|
end
|
649
654
|
|
650
|
-
it 'should generate secured api keys' do
|
655
|
+
it 'should generate secured api keys (old syntax)' do
|
651
656
|
key = Algolia.generate_secured_api_key('my_api_key', '(public,user1)')
|
652
657
|
key.should eq(OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), 'my_api_key', '(public,user1)'))
|
653
658
|
key = Algolia.generate_secured_api_key('my_api_key', '(public,user1)', 42)
|
@@ -658,6 +663,13 @@ describe 'Client' do
|
|
658
663
|
key.should eq(OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), 'my_api_key', 'public,(premium,vip)'))
|
659
664
|
end
|
660
665
|
|
666
|
+
it 'should generate secured api keys (new syntax)' do
|
667
|
+
key = Algolia.generate_secured_api_key('my_api_key', :tagFilters => '(public,user1)')
|
668
|
+
key.should eq(Base64.encode64("#{OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), 'my_api_key', 'tagFilters=%28public%2Cuser1%29')}tagFilters=%28public%2Cuser1%29").gsub("\n", ''))
|
669
|
+
key = Algolia.generate_secured_api_key('182634d8894831d5dbce3b3185c50881', :tagFilters => '(public,user1)', :userToken => 42)
|
670
|
+
key.should eq('OGYwN2NlNTdlOGM2ZmM4MjA5NGM0ZmYwNTk3MDBkNzMzZjQ0MDI3MWZjNTNjM2Y3YTAzMWM4NTBkMzRiNTM5YnRhZ0ZpbHRlcnM9JTI4cHVibGljJTJDdXNlcjElMjkmdXNlclRva2VuPTQy')
|
671
|
+
end
|
672
|
+
|
661
673
|
it 'Check attributes multipleQueries' do
|
662
674
|
res = Algolia.multiple_queries([{:index_name => safe_index_name("àlgol?a"), "query" => ""}])
|
663
675
|
res.should have_key('results')
|
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.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|