algoliasearch 1.11.0 → 1.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +3 -0
- data/ChangeLog +3 -0
- data/Gemfile +1 -1
- data/Gemfile.lock +2 -5
- data/README.md +323 -153
- data/algoliasearch.gemspec +3 -3
- data/lib/algolia/client.rb +1 -0
- data/lib/algolia/index.rb +50 -28
- data/lib/algolia/protocol.rb +4 -0
- data/lib/algolia/version.rb +1 -1
- data/spec/client_spec.rb +78 -0
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 47343e37f75fab97f3f03b5077d1422376a0995f
|
4
|
+
data.tar.gz: d0c473b3587f99c0b64410fea213dd73f4e83ae9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2c853a919b2dc0a269b28890fa431576dd55424776c77a784dab5bf4e0c536456f9ad1fb67e3a0378ba6f45c3c832f5b018e104866ec5ee731010550c5ffc347
|
7
|
+
data.tar.gz: 5e12669bdc370347f622652079fe882ed836ae6726fe123cc8d2ddfc8b80c6a1a395525dc5ae96fc33a55f4896fc37f0e0f746d1b550773979c5480cf44c4d28
|
data/.travis.yml
CHANGED
data/ChangeLog
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -31,7 +31,7 @@ GEM
|
|
31
31
|
net-http-persistent (>= 2.7)
|
32
32
|
net-http-pipeline
|
33
33
|
highline (1.6.21)
|
34
|
-
httpclient (2.8.2.
|
34
|
+
httpclient (2.8.2.4)
|
35
35
|
json (1.8.3)
|
36
36
|
json (1.8.3-java)
|
37
37
|
launchy (2.4.3)
|
@@ -311,7 +311,7 @@ PLATFORMS
|
|
311
311
|
DEPENDENCIES
|
312
312
|
coveralls
|
313
313
|
highline (< 1.7.0)
|
314
|
-
httpclient (~> 2.8.2)
|
314
|
+
httpclient (~> 2.8.2.4)
|
315
315
|
json (>= 1.5.1)
|
316
316
|
mime-types (< 2.0)
|
317
317
|
rake
|
@@ -323,6 +323,3 @@ DEPENDENCIES
|
|
323
323
|
simplecov
|
324
324
|
travis
|
325
325
|
webmock
|
326
|
-
|
327
|
-
BUNDLED WITH
|
328
|
-
1.11.2
|
data/README.md
CHANGED
@@ -48,7 +48,7 @@ Indexing
|
|
48
48
|
|
49
49
|
1. [Add objects](#add-objects---add_objects)
|
50
50
|
1. [Update objects](#update-objects---save_objects)
|
51
|
-
1. [Partial update](#partial-update---partial_update_objects)
|
51
|
+
1. [Partial update objects](#partial-update-objects---partial_update_objects)
|
52
52
|
1. [Delete objects](#delete-objects---delete_objects)
|
53
53
|
|
54
54
|
Settings
|
@@ -196,7 +196,7 @@ index.set_settings({"customRanking" => ["desc(followers)"]})
|
|
196
196
|
You can also configure the list of attributes you want to index by order of importance (first = most important):
|
197
197
|
|
198
198
|
```ruby
|
199
|
-
index.set_settings({"
|
199
|
+
index.set_settings({"searchableAttributes" => ["lastname", "firstname", "company",
|
200
200
|
"email", "city", "address"]})
|
201
201
|
```
|
202
202
|
|
@@ -358,17 +358,17 @@ The server response will look like:
|
|
358
358
|
|
359
359
|
- `nbHits` (integer): Number of hits that the search query matched.
|
360
360
|
|
361
|
-
- `page` (integer): Index of the current page (zero-based). See the [`page`](#page) search parameter.
|
361
|
+
- `page` (integer): Index of the current page (zero-based). See the [`page`](#page) search parameter. *Note: Not returned if you use `offset`/`length` for pagination.*
|
362
362
|
|
363
|
-
- `hitsPerPage` (integer): Maximum number of hits returned per page. See the [`hitsPerPage`](#hitsperpage) search parameter.
|
363
|
+
- `hitsPerPage` (integer): Maximum number of hits returned per page. See the [`hitsPerPage`](#hitsperpage) search parameter. *Note: Not returned if you use `offset`/`length` for pagination.*
|
364
364
|
|
365
|
-
- `nbPages` (integer): Number of pages corresponding to the number of hits. Basically, `ceil(nbHits / hitsPerPage)`.
|
365
|
+
- `nbPages` (integer): Number of pages corresponding to the number of hits. Basically, `ceil(nbHits / hitsPerPage)`. *Note: Not returned if you use `offset`/`length` for pagination.*
|
366
366
|
|
367
367
|
- `processingTimeMS` (integer): Time that the server took to process the request, in milliseconds. *Note: This does not include network time.*
|
368
368
|
|
369
369
|
- `query` (string): An echo of the query text. See the [`query`](#query) search parameter.
|
370
370
|
|
371
|
-
- `queryAfterRemoval` (string, optional): *Note: Only returned when [`removeWordsIfNoResults`](#removewordsifnoresults) is set
|
371
|
+
- `queryAfterRemoval` (string, optional): *Note: Only returned when [`removeWordsIfNoResults`](#removewordsifnoresults) is set to `lastWords` or `firstWords`.* A markup text indicating which parts of the original query have been removed in order to retrieve a non-empty result set. The removed parts are surrounded by `<em>` tags.
|
372
372
|
|
373
373
|
- `params` (string, URL-encoded): An echo of all search parameters.
|
374
374
|
|
@@ -382,7 +382,7 @@ When [`getRankingInfo`](#getrankinginfo) is set to `true`, the following additio
|
|
382
382
|
|
383
383
|
- `serverUsed` (string): Actual host name of the server that processed the request. (Our DNS supports automatic failover and load balancing, so this may differ from the host name used in the request.)
|
384
384
|
|
385
|
-
- `parsedQuery` (string): The query string that will be searched, after normalization.
|
385
|
+
- `parsedQuery` (string): The query string that will be searched, after normalization. Normalization includes removing stop words (if [removeStopWords](#removestopwords) is enabled), and transforming portions of the query string into phrase queries (see [advancedSyntax](#advancedsyntax)).
|
386
386
|
|
387
387
|
- `timeoutCounts` (boolean): Whether a timeout was hit when computing the facet counts. When `true`, the counts will be interpolated (i.e. approximate). See also `exhaustiveFacetsCount`.
|
388
388
|
|
@@ -426,6 +426,7 @@ Parameters that can also be used in a setSettings also have the `indexing` [scop
|
|
426
426
|
**Attributes**
|
427
427
|
|
428
428
|
- [attributesToRetrieve](#attributestoretrieve) `settings`, `search`
|
429
|
+
- [restrictSearchableAttributes](#restrictsearchableattributes) `search`
|
429
430
|
|
430
431
|
**Filtering / Faceting**
|
431
432
|
|
@@ -440,11 +441,14 @@ Parameters that can also be used in a setSettings also have the `indexing` [scop
|
|
440
441
|
- [highlightPreTag](#highlightpretag) `settings`, `search`
|
441
442
|
- [highlightPostTag](#highlightposttag) `settings`, `search`
|
442
443
|
- [snippetEllipsisText](#snippetellipsistext) `settings`, `search`
|
444
|
+
- [restrictHighlightAndSnippetArrays](#restricthighlightandsnippetarrays) `settings`, `search`
|
443
445
|
|
444
446
|
**Pagination**
|
445
447
|
|
446
448
|
- [page](#page) `search`
|
447
449
|
- [hitsPerPage](#hitsperpage) `settings`, `search`
|
450
|
+
- [offset](#offset) `search`
|
451
|
+
- [length](#length) `search`
|
448
452
|
|
449
453
|
**Typos**
|
450
454
|
|
@@ -472,6 +476,7 @@ Parameters that can also be used in a setSettings also have the `indexing` [scop
|
|
472
476
|
- [advancedSyntax](#advancedsyntax) `settings`, `search`
|
473
477
|
- [optionalWords](#optionalwords) `settings`, `search`
|
474
478
|
- [removeStopWords](#removestopwords) `settings`, `search`
|
479
|
+
- [disableExactOnAttributes](#disableexactonattributes) `settings`, `search`
|
475
480
|
- [exactOnSingleWordQuery](#exactonsinglewordquery) `settings`, `search`
|
476
481
|
- [alternativesAsExact](#alternativesasexact) `settings`, `search`
|
477
482
|
|
@@ -483,9 +488,47 @@ Parameters that can also be used in a setSettings also have the `indexing` [scop
|
|
483
488
|
- [tagFilters (deprecated)](#tagfilters-deprecated) `search`
|
484
489
|
- [facetFilters (deprecated)](#facetfilters-deprecated) `search`
|
485
490
|
- [analytics](#analytics) `search`
|
491
|
+
- [analyticsTags](#analyticstags) `search`
|
492
|
+
- [synonyms](#synonyms) `search`
|
493
|
+
- [replaceSynonymsInHighlight](#replacesynonymsinhighlight) `search`, `settings`
|
494
|
+
- [minProximity](#minproximity) `search`, `settings`
|
486
495
|
|
487
496
|
<!--/PARAMETERS_LINK-->
|
488
497
|
|
498
|
+
### Multiple queries - `multiple_queries`
|
499
|
+
|
500
|
+
You can send multiple queries with a single API call using a batch of queries:
|
501
|
+
|
502
|
+
```ruby
|
503
|
+
# perform 3 queries in a single API call:
|
504
|
+
# - 1st query targets index `categories`
|
505
|
+
# - 2nd and 3rd queries target index `products`
|
506
|
+
res = Algolia.multiple_queries([{:index_name => "categories", "query" => my_query_string, "hitsPerPage" => 3}
|
507
|
+
, {:index_name => "products", "query" => my_query_string, "hitsPerPage" => 3, "filters" => "_tags:promotion"}
|
508
|
+
, {:index_name => "products", "query" => my_query_string, "hitsPerPage" => 10}])
|
509
|
+
|
510
|
+
puts res["results"]
|
511
|
+
```
|
512
|
+
|
513
|
+
You can specify a `strategy` parameter to optimize your multiple queries:
|
514
|
+
|
515
|
+
- `none`: Execute the sequence of queries until the end.
|
516
|
+
- `stopIfEnoughMatches`: Execute the sequence of queries until the number of hits is reached by the sum of hits.
|
517
|
+
|
518
|
+
#### Response
|
519
|
+
|
520
|
+
The resulting JSON contains the following fields:
|
521
|
+
|
522
|
+
- `results` (array): The results for each request, in the order they were submitted. The contents are the same as in [Search in an index](#search-in-an-index---search).
|
523
|
+
|
524
|
+
Each result also includes the following additional fields:
|
525
|
+
|
526
|
+
- `index` (string): The name of the targeted index.
|
527
|
+
|
528
|
+
- `processed` (boolean, optional): *Note: Only returned when `strategy` is `stopIfEnoughmatches`.* Whether the query was processed.
|
529
|
+
|
530
|
+
|
531
|
+
|
489
532
|
### Find by IDs - `get_objects`
|
490
533
|
|
491
534
|
You can easily retrieve an object using its `objectID` and optionally specify a comma separated list of attributes you want:
|
@@ -516,21 +559,33 @@ res = index.get_objects(["myID", "myID2"])
|
|
516
559
|
|
517
560
|
Each entry in an index has a unique identifier called `objectID`. There are two ways to add an entry to the index:
|
518
561
|
|
519
|
-
1.
|
520
|
-
2.
|
562
|
+
1. Supplying your own `objectID`.
|
563
|
+
2. Using automatic `objectID` assignment. You will be able to access it in the answer.
|
521
564
|
|
522
565
|
You don't need to explicitly create an index, it will be automatically created the first time you add an object.
|
523
566
|
Objects are schema less so you don't need any configuration to start indexing. If you wish to configure things, the settings section provides details about advanced settings.
|
524
567
|
|
525
|
-
Example with automatic `objectID`
|
568
|
+
Example with automatic `objectID` assignments:
|
526
569
|
|
527
570
|
```ruby
|
528
|
-
res = index.
|
529
|
-
|
530
|
-
|
571
|
+
res = index.add_objects([{"firstname" => "Jimmie",
|
572
|
+
"lastname" => "Barninger"},
|
573
|
+
{"firstname" => "Warren",
|
574
|
+
"lastname" => "Speach"}])
|
531
575
|
```
|
532
576
|
|
533
|
-
Example with manual `objectID`
|
577
|
+
Example with manual `objectID` assignments:
|
578
|
+
|
579
|
+
```ruby
|
580
|
+
res = index.add_objects([{"objectID" => "1",
|
581
|
+
"firstname" => "Jimmie",
|
582
|
+
"lastname" => "Barninger"},
|
583
|
+
{"objectID" => "2",
|
584
|
+
"firstname" => "Warren",
|
585
|
+
"lastname" => "Speach"}])
|
586
|
+
```
|
587
|
+
|
588
|
+
To add a single object, use the `[Add object](#add-object---add_object)` method:
|
534
589
|
|
535
590
|
```ruby
|
536
591
|
res = index.add_object({"firstname" => "Jimmie",
|
@@ -538,7 +593,6 @@ res = index.add_object({"firstname" => "Jimmie",
|
|
538
593
|
puts "ObjectID=" + res["objectID"]
|
539
594
|
```
|
540
595
|
|
541
|
-
|
542
596
|
### Update objects - `save_objects`
|
543
597
|
|
544
598
|
You have three options when updating an existing object:
|
@@ -547,7 +601,18 @@ You have three options when updating an existing object:
|
|
547
601
|
2. Replace only some attributes.
|
548
602
|
3. Apply an operation to some attributes.
|
549
603
|
|
550
|
-
Example on how to replace all attributes
|
604
|
+
Example on how to replace all attributes existing objects:
|
605
|
+
|
606
|
+
```ruby
|
607
|
+
res = index.save_objects([{"firstname" => "Jimmie",
|
608
|
+
"lastname" => "Barninger",
|
609
|
+
"objectID" => "myID1"},
|
610
|
+
{"firstname" => "Warren",
|
611
|
+
"lastname" => "Speach",
|
612
|
+
"objectID" => "myID2"}])
|
613
|
+
```
|
614
|
+
|
615
|
+
To update a single object, you can use the `[Update object](#update-object---save_object) method:
|
551
616
|
|
552
617
|
```ruby
|
553
618
|
index.save_object({"firstname" => "Jimmie",
|
@@ -556,7 +621,8 @@ index.save_object({"firstname" => "Jimmie",
|
|
556
621
|
"objectID" => "myID"})
|
557
622
|
```
|
558
623
|
|
559
|
-
|
624
|
+
|
625
|
+
### Partial update objects - `partial_update_objects`
|
560
626
|
|
561
627
|
You have many ways to update an object's attributes:
|
562
628
|
|
@@ -615,10 +681,25 @@ index.partial_update_object({"price" => {"value" => 42, "_operation" => "Decreme
|
|
615
681
|
Note: Here we are decrementing the value by `42`. To decrement just by one, put
|
616
682
|
`value:1`.
|
617
683
|
|
684
|
+
To partial update multiple objects using one API call, you can use the `[Partial update objects](#partial-update-objects---partial_update_objects)` method:
|
685
|
+
|
686
|
+
```ruby
|
687
|
+
res = index.partial_update_objects([{"firstname" => "Jimmie",
|
688
|
+
"objectID" => "SFO"},
|
689
|
+
{"firstname" => "Warren",
|
690
|
+
"objectID" => "myID2"}])
|
691
|
+
```
|
692
|
+
|
618
693
|
|
619
694
|
### Delete objects - `delete_objects`
|
620
695
|
|
621
|
-
You can delete
|
696
|
+
You can delete objects using their `objectID`:
|
697
|
+
|
698
|
+
```ruby
|
699
|
+
res = index.delete_objects(["myID1", "myID2"])
|
700
|
+
```
|
701
|
+
|
702
|
+
To delete a single object, you can use the `[Delete object](#delete-object---delete_object)` method:
|
622
703
|
|
623
704
|
```ruby
|
624
705
|
index.delete_object("myID")
|
@@ -668,7 +749,7 @@ the biggest `taskID` with `wait_task`.
|
|
668
749
|
You can retrieve settings:
|
669
750
|
|
670
751
|
```ruby
|
671
|
-
|
752
|
+
settings = index.get_settings
|
672
753
|
puts settings.to_json
|
673
754
|
```
|
674
755
|
|
@@ -682,12 +763,12 @@ index.set_settings({"customRanking" => ["desc(followers)"]})
|
|
682
763
|
|
683
764
|
Performance wise, it's better to do a `set_settings` before pushing the data
|
684
765
|
|
685
|
-
####
|
766
|
+
#### Replica settings
|
686
767
|
|
687
|
-
You can forward all settings updates to the
|
768
|
+
You can forward all settings updates to the replicas of an index by using the `forwardToReplicas` option:
|
688
769
|
|
689
770
|
```ruby
|
690
|
-
index.set_settings({"customRanking" => ["desc(followers)"]}, {"
|
771
|
+
index.set_settings({"customRanking" => ["desc(followers)"]}, {"forwardToReplicas" => true})
|
691
772
|
```
|
692
773
|
|
693
774
|
|
@@ -696,14 +777,14 @@ index.set_settings({"customRanking" => ["desc(followers)"]}, {"forwardToSlave" =
|
|
696
777
|
|
697
778
|
<!--PARAMETERS_LINK-->
|
698
779
|
|
699
|
-
Here is the list of parameters you can use with the set settings method (`
|
780
|
+
Here is the list of parameters you can use with the set settings method (`settings` [scope](#scope)).
|
700
781
|
|
701
782
|
|
702
|
-
Parameters that can be overridden at search time also have the `search` [scope](#scope)
|
783
|
+
Parameters that can be overridden at search time also have the `search` [scope](#scope).
|
703
784
|
|
704
785
|
**Attributes**
|
705
786
|
|
706
|
-
- [
|
787
|
+
- [searchableAttributes](#searchableattributes) `settings`
|
707
788
|
- [attributesForFaceting](#attributesforfaceting) `settings`
|
708
789
|
- [attributesToRetrieve](#attributestoretrieve) `settings`, `search`
|
709
790
|
- [unretrievableAttributes](#unretrievableattributes) `settings`
|
@@ -712,7 +793,7 @@ Parameters that can be overridden at search time also have the `search` [scope](
|
|
712
793
|
|
713
794
|
- [ranking](#ranking) `settings`
|
714
795
|
- [customRanking](#customranking) `settings`
|
715
|
-
- [
|
796
|
+
- [replicas](#replicas) `settings`
|
716
797
|
|
717
798
|
**Filtering / Faceting**
|
718
799
|
|
@@ -756,7 +837,7 @@ Parameters that can be overridden at search time also have the `search` [scope](
|
|
756
837
|
|
757
838
|
- [attributeForDistinct](#attributefordistinct) `settings`
|
758
839
|
- [distinct](#distinct) `settings`, `search`
|
759
|
-
- [
|
840
|
+
- [numericAttributesForFiltering](#numericattributesforfiltering) `settings`
|
760
841
|
- [allowCompressionOfIntegerArray](#allowcompressionofintegerarray) `settings`
|
761
842
|
- [altCorrections](#altcorrections) `settings`
|
762
843
|
- [placeholders](#placeholders) `settings`
|
@@ -788,17 +869,17 @@ They are three scopes:
|
|
788
869
|
|
789
870
|
**Attributes**
|
790
871
|
|
872
|
+
- [searchableAttributes](#searchableattributes) `settings`
|
791
873
|
- [attributesForFaceting](#attributesforfaceting) `settings`
|
792
|
-
- [attributesToIndex](#attributestoindex) `settings`
|
793
|
-
- [attributesToRetrieve](#attributestoretrieve) `settings`, `search`
|
794
874
|
- [unretrievableAttributes](#unretrievableattributes) `settings`
|
795
|
-
|
875
|
+
- [attributesToRetrieve](#attributestoretrieve) `settings`, `search`
|
876
|
+
- [restrictSearchableAttributes](#restrictsearchableattributes) `search`
|
796
877
|
|
797
878
|
**Ranking**
|
798
879
|
|
799
880
|
- [ranking](#ranking) `settings`
|
800
881
|
- [customRanking](#customranking) `settings`
|
801
|
-
- [
|
882
|
+
- [replicas](#replicas) `settings`
|
802
883
|
|
803
884
|
**Filtering / Faceting**
|
804
885
|
|
@@ -819,6 +900,8 @@ They are three scopes:
|
|
819
900
|
|
820
901
|
- [page](#page) `search`
|
821
902
|
- [hitsPerPage](#hitsperpage) `settings`, `search`
|
903
|
+
- [offset](#offset) `search`
|
904
|
+
- [length](#length) `search`
|
822
905
|
|
823
906
|
**Typos**
|
824
907
|
|
@@ -857,14 +940,18 @@ They are three scopes:
|
|
857
940
|
- [attributeForDistinct](#attributefordistinct) `settings`
|
858
941
|
- [distinct](#distinct) `settings`, `search`
|
859
942
|
- [getRankingInfo](#getrankinginfo) `search`
|
860
|
-
- [
|
943
|
+
- [numericAttributesForFiltering](#numericattributesforfiltering) `settings`
|
861
944
|
- [allowCompressionOfIntegerArray](#allowcompressionofintegerarray) `settings`
|
862
945
|
- [numericFilters (deprecated)](#numericfilters-deprecated) `search`
|
863
946
|
- [tagFilters (deprecated)](#tagfilters-deprecated) `search`
|
864
947
|
- [facetFilters (deprecated)](#facetfilters-deprecated) `search`
|
865
948
|
- [analytics](#analytics) `search`
|
866
|
-
- [
|
949
|
+
- [analyticsTags](#analyticstags) `search`
|
950
|
+
- [synonyms](#synonyms) `search`
|
951
|
+
- [replaceSynonymsInHighlight](#replacesynonymsinhighlight) `search`, `settings`
|
867
952
|
- [placeholders](#placeholders) `settings`
|
953
|
+
- [altCorrections](#altcorrections) `settings`
|
954
|
+
- [minProximity](#minproximity) `search`, `settings`
|
868
955
|
|
869
956
|
### Search
|
870
957
|
|
@@ -879,11 +966,12 @@ The instant search query string, used to set the string you want to search in yo
|
|
879
966
|
|
880
967
|
### Attributes
|
881
968
|
|
882
|
-
####
|
969
|
+
#### searchableAttributes
|
883
970
|
|
884
971
|
- scope: `settings`
|
885
972
|
- type: `array of strings`
|
886
973
|
- default: `*`
|
974
|
+
- formerly known as: `attributesToIndex`
|
887
975
|
|
888
976
|
|
889
977
|
The list of attributes you want index (i.e. to make searchable).
|
@@ -895,7 +983,7 @@ This parameter has two important uses:
|
|
895
983
|
|
896
984
|
1. **Limit the attributes to index.** For example, if you store the URL of a picture, you want to store it and be able to retrieve it, but you probably don't want to search in the URL.
|
897
985
|
|
898
|
-
2. **Control part of the ranking.** The contents of the `
|
986
|
+
2. **Control part of the ranking.** The contents of the `searchableAttributes` parameter impacts ranking in two complementary ways:
|
899
987
|
|
900
988
|
First, the order in which attributes are listed defines their ranking priority: matches in attributes at the beginning of the list will be considered more important than matches in attributes further down the list. To assign the same priority to several attributes, pass them within the same string, separated by commas. For example, by specifying `["title,"alternative_title", "text"]`, `title` and `alternative_title` will have the same priority, but a higher priority than `text`.
|
901
989
|
|
@@ -950,13 +1038,13 @@ You can also use `*` to retrieve all values when an **attributesToRetrieve** set
|
|
950
1038
|
|
951
1039
|
- scope: `search`
|
952
1040
|
- type: `array of strings`
|
953
|
-
- default: `
|
1041
|
+
- default: `searchableAttributes`
|
954
1042
|
|
955
1043
|
|
956
|
-
List of attributes you want to use for textual search (must be a subset of the `
|
1044
|
+
List of attributes you want to use for textual search (must be a subset of the `searchableAttributes` index setting).
|
957
1045
|
Attributes are separated with a comma such as `"name,address"`.
|
958
1046
|
You can also use JSON string array encoding such as `encodeURIComponent("[\"name\",\"address\"]")`.
|
959
|
-
By default, all attributes specified in the `
|
1047
|
+
By default, all attributes specified in the `searchableAttributes` settings are used to search.
|
960
1048
|
|
961
1049
|
|
962
1050
|
### Ranking
|
@@ -976,7 +1064,7 @@ We have nine available criterion:
|
|
976
1064
|
* `geo`: Sort according to decreasing distance when performing a geo location based search.
|
977
1065
|
* `words`: Sort according to the number of query words matched by decreasing order. This parameter is useful when you use the `optionalWords` query parameter to have results with the most matched words first.
|
978
1066
|
* `proximity`: Sort according to the proximity of the query words in hits.
|
979
|
-
* `attribute`: Sort according to the order of attributes defined by
|
1067
|
+
* `attribute`: Sort according to the order of attributes defined by searchableAttributes.
|
980
1068
|
* `exact`:
|
981
1069
|
* If the user query contains one word: sort objects having an attribute that is exactly the query word before others. For example, if you search for the TV show "V", you want to find it with the "V" query and avoid getting all popular TV shows starting by the letter V before it.
|
982
1070
|
* If the user query contains multiple words: sort according to the number of words that matched exactly (not as a prefix).
|
@@ -1004,11 +1092,12 @@ For example, `"customRanking" => ["desc(population)", "asc(name)"]`.
|
|
1004
1092
|
To get a full description of how the Custom Ranking works,
|
1005
1093
|
you can have a look at our [Ranking guide](https://www.algolia.com/doc/guides/relevance/ranking).
|
1006
1094
|
|
1007
|
-
####
|
1095
|
+
#### replicas
|
1008
1096
|
|
1009
1097
|
- scope: `settings`
|
1010
1098
|
- type: `array of strings`
|
1011
1099
|
- default: `[]`
|
1100
|
+
- formerly known as: `slaves`
|
1012
1101
|
|
1013
1102
|
|
1014
1103
|
The list of indices on which you want to replicate all write operations.
|
@@ -1019,7 +1108,7 @@ If you want to use different ranking configurations depending of the use case,
|
|
1019
1108
|
you need to create one index per ranking configuration.
|
1020
1109
|
|
1021
1110
|
This option enables you to perform write operations only on this index and automatically
|
1022
|
-
update
|
1111
|
+
update replica indices with the same operations.
|
1023
1112
|
|
1024
1113
|
### Filtering / Faceting
|
1025
1114
|
|
@@ -1105,6 +1194,10 @@ Limit the number of facet values returned for each facet.
|
|
1105
1194
|
|
1106
1195
|
For example, `maxValuesPerFacet=10` will retrieve a maximum of 10 values per facet.
|
1107
1196
|
|
1197
|
+
**Warnings**
|
1198
|
+
|
1199
|
+
- The engine has a hard limit on the `maxValuesPerFacet` of `1000`. Any value above that will be interpreted by the engine as being `1000`.
|
1200
|
+
|
1108
1201
|
### Highlighting / Snippeting
|
1109
1202
|
|
1110
1203
|
#### attributesToHighlight
|
@@ -1204,6 +1297,28 @@ Pagination parameter used to select the page to retrieve.
|
|
1204
1297
|
|
1205
1298
|
Pagination parameter used to select the number of hits per page.
|
1206
1299
|
|
1300
|
+
#### offset
|
1301
|
+
|
1302
|
+
- scope: `search`
|
1303
|
+
- type: `integer`
|
1304
|
+
- default: `null`
|
1305
|
+
|
1306
|
+
|
1307
|
+
Offset of the first hit to return (zero-based).
|
1308
|
+
|
1309
|
+
**Warning:** In most cases, `page`/`hitsPerPage` is the recommended method for pagination; `offset`/`length` is reserved for advanced use.
|
1310
|
+
|
1311
|
+
#### length
|
1312
|
+
|
1313
|
+
- scope: `search`
|
1314
|
+
- type: `integer`
|
1315
|
+
- default: `null`
|
1316
|
+
|
1317
|
+
|
1318
|
+
Number of hits to return.
|
1319
|
+
|
1320
|
+
**Warning:** In most cases, `page`/`hitsPerPage` is the recommended method for pagination; `offset`/`length` is reserved for advanced use.
|
1321
|
+
|
1207
1322
|
### Typos
|
1208
1323
|
|
1209
1324
|
#### minWordSizefor1Typo
|
@@ -1265,7 +1380,7 @@ If set to true, plural won't be considered as a typo. For example, car and cars,
|
|
1265
1380
|
|
1266
1381
|
|
1267
1382
|
List of attributes on which you want to disable typo tolerance
|
1268
|
-
(must be a subset of the `
|
1383
|
+
(must be a subset of the `searchableAttributes` index setting).
|
1269
1384
|
|
1270
1385
|
Attributes are separated with a comma such as `"name,address"`.
|
1271
1386
|
You can also use JSON string array encoding such as `encodeURIComponent("[\"name\",\"address\"]")`.
|
@@ -1523,7 +1638,7 @@ For most use cases, it is better to not use this feature as people search by key
|
|
1523
1638
|
|
1524
1639
|
|
1525
1640
|
List of attributes on which you want to disable prefix matching
|
1526
|
-
(must be a subset of the `
|
1641
|
+
(must be a subset of the `searchableAttributes` index setting).
|
1527
1642
|
|
1528
1643
|
This setting is useful on attributes that contain string that should not be matched as a prefix
|
1529
1644
|
(for example a product SKU).
|
@@ -1537,7 +1652,7 @@ This setting is useful on attributes that contain string that should not be matc
|
|
1537
1652
|
|
1538
1653
|
|
1539
1654
|
List of attributes on which you want to disable the computation of `exact` criteria
|
1540
|
-
(must be a subset of the `
|
1655
|
+
(must be a subset of the `searchableAttributes` index setting).
|
1541
1656
|
|
1542
1657
|
#### exactOnSingleWordQuery
|
1543
1658
|
|
@@ -1617,11 +1732,12 @@ you can have a look at our [guide on distinct](https://www.algolia.com/doc/searc
|
|
1617
1732
|
If set to true,
|
1618
1733
|
the result hits will contain ranking information in the **_rankingInfo** attribute.
|
1619
1734
|
|
1620
|
-
####
|
1735
|
+
#### numericAttributesForFiltering
|
1621
1736
|
|
1622
1737
|
- scope: `settings`
|
1623
1738
|
- type: `array of strings`
|
1624
1739
|
- default: ``
|
1740
|
+
- formerly known as: `numericAttributesToIndex`
|
1625
1741
|
|
1626
1742
|
|
1627
1743
|
All numerical attributes are automatically indexed as numerical filters
|
@@ -1727,6 +1843,33 @@ For example, `[["category:Book","category:Movie"],"author:John%20Doe"]`.
|
|
1727
1843
|
|
1728
1844
|
If set to false, this query will not be taken into account in the analytics feature.
|
1729
1845
|
|
1846
|
+
#### analyticsTags
|
1847
|
+
|
1848
|
+
- scope: `search`
|
1849
|
+
- type: `array of strings`
|
1850
|
+
- default: `null`
|
1851
|
+
|
1852
|
+
|
1853
|
+
If set, tag your query with the specified identifiers. Tags can then be used in the Analytics to analyze a subset of searches only.
|
1854
|
+
|
1855
|
+
#### synonyms
|
1856
|
+
|
1857
|
+
- scope: `search`
|
1858
|
+
- type: `boolean`
|
1859
|
+
- default: `true`
|
1860
|
+
|
1861
|
+
|
1862
|
+
If set to `false`, the search will not use the synonyms defined for the targeted index.
|
1863
|
+
|
1864
|
+
#### replaceSynonymsInHighlight
|
1865
|
+
|
1866
|
+
- scope: `search`, `settings`
|
1867
|
+
- type: `boolean`
|
1868
|
+
- default: `true`
|
1869
|
+
|
1870
|
+
|
1871
|
+
If set to `false`, words matched via synonym expansion will not be replaced by the matched synonym in the highlighted result.
|
1872
|
+
|
1730
1873
|
#### placeholders
|
1731
1874
|
|
1732
1875
|
- scope: `settings`
|
@@ -1774,6 +1917,19 @@ For example:
|
|
1774
1917
|
]
|
1775
1918
|
```
|
1776
1919
|
|
1920
|
+
#### minProximity
|
1921
|
+
|
1922
|
+
- scope: `search`, `settings`
|
1923
|
+
- type: `integer`
|
1924
|
+
- default: `1`
|
1925
|
+
|
1926
|
+
|
1927
|
+
Configure the precision of the `proximity` ranking criterion. By default, the minimum (and best) proximity value distance between 2 matching words is 1. Setting it to 2 (or 3) would allow 1 (or 2) words to be found between the matching words without degrading the proximity ranking value.
|
1928
|
+
|
1929
|
+
Considering the query *“javascript framework”*, if you set `minProximity=2`, the records *“JavaScript framework”* and *“JavaScript charting framework”* will get the same proximity score, even if the second contains a word between the two matching words.
|
1930
|
+
|
1931
|
+
**Note:** the maximum `minProximity` that can be set is 7. Any higher value will disable the `proximity` criterion from the ranking formula.
|
1932
|
+
|
1777
1933
|
|
1778
1934
|
## Manage Indices
|
1779
1935
|
|
@@ -1845,7 +2001,7 @@ The move_index method will overwrite the destination index, and delete the tempo
|
|
1845
2001
|
**Warning**
|
1846
2002
|
|
1847
2003
|
The move_index operation will override all settings of the destination,
|
1848
|
-
There is one exception for the [
|
2004
|
+
There is one exception for the [replicas](#replicas) parameter which is not impacted.
|
1849
2005
|
|
1850
2006
|
For example, if you want to fully update your index `MyIndex` every night, we recommend the following process:
|
1851
2007
|
|
@@ -1853,13 +2009,13 @@ For example, if you want to fully update your index `MyIndex` every night, we re
|
|
1853
2009
|
and [Get synonym](#get-synonym---get_synonym).
|
1854
2010
|
1. Apply settings and synonyms to the temporary index `MyTmpIndex`, (this will create the `MyTmpIndex` index)
|
1855
2011
|
using [Set settings](#set-settings---set_settings) and [Batch synonyms](#batch-synonyms---batch_synonyms)
|
1856
|
-
(make sure to remove the [
|
2012
|
+
(make sure to remove the [replicas](#replicas) parameter from the settings if it exists).
|
1857
2013
|
1. Import your records into a new index using [Add objects](#add-objects---add_objects).
|
1858
2014
|
1. Atomically replace the index `MyIndex` with the content and settings of the index `MyTmpIndex`
|
1859
2015
|
using the [Move index](#move-index---move_index) method.
|
1860
2016
|
This will automatically override the old index without any downtime on the search.
|
1861
2017
|
1. You'll end up with only one index called `MyIndex`, that contains the records and settings pushed to `MyTmpIndex`
|
1862
|
-
and the
|
2018
|
+
and the replica-indices that were initially attached to `MyIndex` will be in sync with the new data.
|
1863
2019
|
|
1864
2020
|
|
1865
2021
|
|
@@ -1868,22 +2024,57 @@ For example, if you want to fully update your index `MyIndex` every night, we re
|
|
1868
2024
|
|
1869
2025
|
## Api Keys
|
1870
2026
|
|
1871
|
-
|
2027
|
+
### Overview
|
2028
|
+
|
2029
|
+
When creating your Algolia Account, you'll notice there are 3 different API Keys:
|
2030
|
+
|
2031
|
+
- **Admin API Key** - it provides full control of all your indices.
|
2032
|
+
*The admin API key should always be kept secure;
|
2033
|
+
do NOT give it to anybody; do NOT use it from outside your back-end as it will
|
2034
|
+
allow the person who has it to query/change/delete data*
|
2035
|
+
|
2036
|
+
- **Search-Only API Key** - It allows you to search on every indices.
|
2037
|
+
|
2038
|
+
- **Monitoring API Key** - It allows you to access the [Monitoring API](https://www.algolia.com/doc/rest-api/monitoring)
|
2039
|
+
|
2040
|
+
#### Other types of API keys
|
2041
|
+
|
2042
|
+
The *Admin API Key* and *Search-Only API Key* both have really large scope and sometimes you want to give a key to
|
2043
|
+
someone that have restricted permissions, can it be an index, a rate limit, a validity limit, ...
|
2044
|
+
|
2045
|
+
To address those use-cases we have two differents type of keys:
|
1872
2046
|
|
1873
|
-
|
1874
|
-
|
2047
|
+
- **Secured API Keys**
|
2048
|
+
|
2049
|
+
When you need to restrict the scope of the *Search Key*, we recommend to use *Secured API Key*.
|
2050
|
+
You can generate them on the fly (without any call to the API)
|
2051
|
+
from the *Search Only API Key* or any search *User Key* using the [Generate key](#generate-key---generate_secured_api_key) method
|
2052
|
+
|
2053
|
+
- **User API Keys**
|
2054
|
+
|
2055
|
+
If *Secured API Keys* does not meet your requirements, you can make use of *User keys*.
|
2056
|
+
Managing and especially creating those keys requires a call to the API.
|
2057
|
+
|
2058
|
+
We have several methods to manage them:
|
2059
|
+
- [Add user key](#add-user-key---add_user_key)
|
2060
|
+
- [Update user key](#update-user-key---update_user_key)
|
2061
|
+
- [Delete user key](#delete-user-key---delete_user_key)
|
2062
|
+
- [List api keys](#list-api-keys---list_api_keys)
|
2063
|
+
- [Get key permissions](#get-key-permissions---get_user_key_acl)
|
1875
2064
|
|
1876
2065
|
### Generate key - `generate_secured_api_key`
|
1877
2066
|
|
1878
|
-
|
2067
|
+
When you need to restrict the scope of the *Search Key*, we recommend to use *Secured API Key*.
|
2068
|
+
You can generate a *Secured API Key* from the *Search Only API Key* or any search *User API Key*
|
1879
2069
|
|
1880
|
-
|
1881
|
-
|
1882
|
-
|
1883
|
-
|
1884
|
-
|
2070
|
+
There is a few things to know about about *Secured API Keys*
|
2071
|
+
- They always need to be generated **on your backend** using one of our API Client
|
2072
|
+
- You can generate them on the fly (without any call to the API)
|
2073
|
+
- They will not appear on the dashboard as they are generated without any call to the API
|
2074
|
+
- The key you use to generate it **needs to become private** and you should not use it in your frontend.
|
2075
|
+
- The generated secured API key **will inherit any restriction from the search key it has been generated from**
|
1885
2076
|
|
1886
|
-
|
2077
|
+
You can then use the key in your frontend code
|
1887
2078
|
|
1888
2079
|
```js
|
1889
2080
|
var client = algoliasearch('YourApplicationID', '<%= public_api_key %>');
|
@@ -1900,29 +2091,84 @@ index.search('something', function(err, content) {
|
|
1900
2091
|
});
|
1901
2092
|
```
|
1902
2093
|
|
1903
|
-
|
2094
|
+
#### Filters
|
2095
|
+
|
2096
|
+
Every filter set in the API key will always be applied. On top of that [filters](#filters) can be applied
|
2097
|
+
in the query parameters.
|
1904
2098
|
|
1905
2099
|
```ruby
|
1906
2100
|
# generate a public API key for user 42. Here, records are tagged with:
|
1907
2101
|
# - 'user_XXXX' if they are visible by user XXXX
|
1908
|
-
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'filters'=> '_tags:user_42'
|
2102
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'filters'=> '_tags:user_42'}
|
1909
2103
|
```
|
1910
2104
|
|
1911
|
-
|
2105
|
+
**Warning**:
|
1912
2106
|
|
1913
|
-
|
1914
|
-
|
2107
|
+
If you set filters in the key `groups:admin`, and `groups:press OR groups:visitors` in the query parameters,
|
2108
|
+
this will be equivalent to `groups:admin AND (groups:press OR groups:visitors)`
|
1915
2109
|
|
1916
|
-
|
2110
|
+
##### Having one API Key per User
|
1917
2111
|
|
1918
|
-
|
1919
|
-
|
1920
|
-
|
1921
|
-
|
1922
|
-
}
|
2112
|
+
One of the usage of secured API keys, is to have allow users to see only part of an index, when this index
|
2113
|
+
contains the data of all users.
|
2114
|
+
In that case, you can tag all records with their associated `user_id` in order to add a `user_id=42` filter when
|
2115
|
+
generating the *Secured API Key* to retrieve only what a user is tagged in.
|
1923
2116
|
|
1924
|
-
|
1925
|
-
|
2117
|
+
**Warning**
|
2118
|
+
If you're generating *Secured API Keys* using the [JavaScript client](http://github.com/algolia/algoliasearch-client-js) in your frontend,
|
2119
|
+
it will result in a security breach since the user is able to modify the `tagFilters` you've set
|
2120
|
+
by modifying the code from the browser.
|
2121
|
+
|
2122
|
+
#### Valid Until
|
2123
|
+
|
2124
|
+
You can set a Unix timestamp used to define the expiration date of the API key
|
2125
|
+
|
2126
|
+
```ruby
|
2127
|
+
# generate a public API key that is valid for 1 hour:
|
2128
|
+
valid_until = Time.now.to_i + 3600
|
2129
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'validUntil'=> valid_until}
|
2130
|
+
```
|
2131
|
+
|
2132
|
+
#### Index Restriction
|
2133
|
+
|
2134
|
+
You can restrict the key to a list of index names allowed for the secured API key
|
2135
|
+
|
2136
|
+
```ruby
|
2137
|
+
# generate a public API key that is restricted to 'index1' and 'index2':
|
2138
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'restrictIndices'=> 'index1,index2'}
|
2139
|
+
```
|
2140
|
+
|
2141
|
+
#### Rate Limiting
|
2142
|
+
|
2143
|
+
If you want to rate limit a secured API Key, the API key you generate the secured api key from need to be rate-limited.
|
2144
|
+
You can do that either via the dashboard or via the API using the
|
2145
|
+
[Add user key](#add-user-key---add_user_key) or [Update user key](#update-user-key---update_user_key) method
|
2146
|
+
|
2147
|
+
##### User Rate Limiting
|
2148
|
+
|
2149
|
+
By default the rate limits will only use the `IP`.
|
2150
|
+
|
2151
|
+
This can be an issue when several of your end users are using the same IP.
|
2152
|
+
To avoid that, you can set a `userToken` query parameter when generating the key.
|
2153
|
+
|
2154
|
+
When set, a unique user will be identified by his `IP + user_token` instead of only by his `IP`.
|
2155
|
+
|
2156
|
+
This allows you to restrict a single user to performing a maximum of `N` API calls per hour,
|
2157
|
+
even if he shares his `IP` with another user.
|
2158
|
+
|
2159
|
+
```ruby
|
2160
|
+
# generate a public API key for user 42. Here, records are tagged with:
|
2161
|
+
# - 'user_XXXX' if they are visible by user XXXX
|
2162
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'filters'=> '_tags:user_42', 'userToken'=> 'user_42'}
|
2163
|
+
```
|
2164
|
+
|
2165
|
+
#### Network restriction
|
2166
|
+
|
2167
|
+
For more protection against API key leaking and reuse you can restrict the key to be valid only from specific IPv4 networks
|
2168
|
+
|
2169
|
+
```ruby
|
2170
|
+
# generate a public API key that is restricted to '192.168.1.0/24':
|
2171
|
+
public_key = Algolia.generate_secured_api_key 'YourSearchOnlyApiKey', {'restrictSources'=> '192.168.1.0/24'}
|
1926
2172
|
```
|
1927
2173
|
|
1928
2174
|
|
@@ -1935,7 +2181,7 @@ index.search('another query', function(err, content) {
|
|
1935
2181
|
|
1936
2182
|
This method saves a single synonym record into the index.
|
1937
2183
|
|
1938
|
-
In this example, we specify true to forward the creation to
|
2184
|
+
In this example, we specify true to forward the creation to replica indices.
|
1939
2185
|
By default the behavior is to save only on the specified index.
|
1940
2186
|
|
1941
2187
|
```ruby
|
@@ -1949,7 +2195,7 @@ index.save_synonym('a-unique-identifier', {
|
|
1949
2195
|
### Batch synonyms - `batch_synonyms`
|
1950
2196
|
|
1951
2197
|
Use the batch method to create a large number of synonyms at once,
|
1952
|
-
forward them to
|
2198
|
+
forward them to replica indices if desired,
|
1953
2199
|
and optionally replace all existing synonyms
|
1954
2200
|
on the index with the content of the batch using the replaceExistingSynonyms parameter.
|
1955
2201
|
|
@@ -1958,7 +2204,7 @@ on a production index. This is the only way to ensure the index always
|
|
1958
2204
|
has a full list of synonyms to use during the indexing of the new list.
|
1959
2205
|
|
1960
2206
|
```ruby
|
1961
|
-
# Batch synonyms, with
|
2207
|
+
# Batch synonyms, with replica forwarding and atomic replacement of existing synonyms
|
1962
2208
|
index.batch_synonyms([{
|
1963
2209
|
:objectID => 'a-unique-identifier',
|
1964
2210
|
:type => 'synonym',
|
@@ -1985,10 +2231,10 @@ in the batch update.
|
|
1985
2231
|
|
1986
2232
|
Use the normal index delete method to delete synonyms,
|
1987
2233
|
specifying the objectID of the synonym record you want to delete.
|
1988
|
-
Forward the deletion to
|
2234
|
+
Forward the deletion to replica indices by setting the forwardToReplicas parameter to true.
|
1989
2235
|
|
1990
2236
|
```ruby
|
1991
|
-
# Delete and forward to
|
2237
|
+
# Delete and forward to replicas
|
1992
2238
|
index.delete_synonym('a-unique-identifier', true)
|
1993
2239
|
```
|
1994
2240
|
|
@@ -2003,7 +2249,7 @@ To atomically replace all synonyms of an index,
|
|
2003
2249
|
use the batch method with the replaceExistingSynonyms parameter set to true.
|
2004
2250
|
|
2005
2251
|
```ruby
|
2006
|
-
# Clear synonyms and forward to
|
2252
|
+
# Clear synonyms and forward to replicas
|
2007
2253
|
index.clear_synonyms(true)
|
2008
2254
|
```
|
2009
2255
|
|
@@ -2042,47 +2288,6 @@ results = index.search_synonyms('street', {
|
|
2042
2288
|
### Custom batch - `batch`
|
2043
2289
|
|
2044
2290
|
You may want to perform multiple operations with one API call to reduce latency.
|
2045
|
-
We expose four methods to perform batch operations:
|
2046
|
-
|
2047
|
-
* Add objects - `add_objects`: Add an array of objects using automatic `objectID` assignment.
|
2048
|
-
* Update objects - `save_objects`: Add or update an array of objects that contains an `objectID` attribute.
|
2049
|
-
* Delete objects - `delete_objects`: Delete an array of objectIDs.
|
2050
|
-
* Partial update - `partial_update_objects`: Partially update an array of objects that contain an `objectID` attribute (only specified attributes will be updated).
|
2051
|
-
|
2052
|
-
Example using automatic `objectID` assignment:
|
2053
|
-
|
2054
|
-
```ruby
|
2055
|
-
res = index.add_objects([{"firstname" => "Jimmie",
|
2056
|
-
"lastname" => "Barninger"},
|
2057
|
-
{"firstname" => "Warren",
|
2058
|
-
"lastname" => "Speach"}])
|
2059
|
-
```
|
2060
|
-
|
2061
|
-
Example with user defined `objectID` (add or update):
|
2062
|
-
|
2063
|
-
```ruby
|
2064
|
-
res = index.save_objects([{"firstname" => "Jimmie",
|
2065
|
-
"lastname" => "Barninger",
|
2066
|
-
"objectID" => "myID1"},
|
2067
|
-
{"firstname" => "Warren",
|
2068
|
-
"lastname" => "Speach",
|
2069
|
-
"objectID" => "myID2"}])
|
2070
|
-
```
|
2071
|
-
|
2072
|
-
Example that deletes a set of records:
|
2073
|
-
|
2074
|
-
```ruby
|
2075
|
-
res = index.delete_objects(["myID1", "myID2"])
|
2076
|
-
```
|
2077
|
-
|
2078
|
-
Example that updates only the `firstname` attribute:
|
2079
|
-
|
2080
|
-
```ruby
|
2081
|
-
res = index.partial_update_objects([{"firstname" => "Jimmie",
|
2082
|
-
"objectID" => "SFO"},
|
2083
|
-
{"firstname" => "Warren",
|
2084
|
-
"objectID" => "myID2"}])
|
2085
|
-
```
|
2086
2291
|
|
2087
2292
|
|
2088
2293
|
|
@@ -2400,41 +2605,6 @@ Algolia.get_user_key("f420238212c54dcfad07ea0aa6d5c45f")
|
|
2400
2605
|
index.get_user_key("71671c38001bf3ac857bc82052485107")
|
2401
2606
|
```
|
2402
2607
|
|
2403
|
-
### Multiple queries - `multiple_queries`
|
2404
|
-
|
2405
|
-
You can send multiple queries with a single API call using a batch of queries:
|
2406
|
-
|
2407
|
-
```ruby
|
2408
|
-
# perform 3 queries in a single API call:
|
2409
|
-
# - 1st query targets index `categories`
|
2410
|
-
# - 2nd and 3rd queries target index `products`
|
2411
|
-
res = Algolia.multiple_queries([{:index_name => "categories", "query" => my_query_string, "hitsPerPage" => 3}
|
2412
|
-
, {:index_name => "products", "query" => my_query_string, "hitsPerPage" => 3, "filters" => "_tags:promotion"}
|
2413
|
-
, {:index_name => "products", "query" => my_query_string, "hitsPerPage" => 10}])
|
2414
|
-
|
2415
|
-
puts res["results"]
|
2416
|
-
```
|
2417
|
-
|
2418
|
-
You can specify a `strategy` parameter to optimize your multiple queries:
|
2419
|
-
|
2420
|
-
- `none`: Execute the sequence of queries until the end.
|
2421
|
-
- `stopIfEnoughMatches`: Execute the sequence of queries until the number of hits is reached by the sum of hits.
|
2422
|
-
|
2423
|
-
#### Response
|
2424
|
-
|
2425
|
-
The resulting JSON contains the following fields:
|
2426
|
-
|
2427
|
-
- `results` (array): The results for each request, in the order they were submitted. The contents are the same as in [Search in an index](#search-in-an-index---search).
|
2428
|
-
|
2429
|
-
Each result also includes the following additional fields:
|
2430
|
-
|
2431
|
-
- `index` (string): The name of the targeted index.
|
2432
|
-
|
2433
|
-
- `processed` (boolean, optional): *Note: Only returned when `strategy` is `stopIfEnoughmatches`.* Whether the query was processed.
|
2434
|
-
|
2435
|
-
|
2436
|
-
|
2437
|
-
|
2438
2608
|
### Get Logs - `get_logs`
|
2439
2609
|
|
2440
2610
|
You can retrieve the latest logs via this API. Each log entry contains:
|
data/algoliasearch.gemspec
CHANGED
@@ -50,17 +50,17 @@ Gem::Specification.new do |s|
|
|
50
50
|
s.specification_version = 4
|
51
51
|
|
52
52
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
53
|
-
s.add_runtime_dependency(%q<httpclient>, ["~> 2.8.2"])
|
53
|
+
s.add_runtime_dependency(%q<httpclient>, ["~> 2.8.2.4"])
|
54
54
|
s.add_runtime_dependency(%q<json>, [">= 1.5.1"])
|
55
55
|
s.add_development_dependency "travis"
|
56
56
|
s.add_development_dependency "rake"
|
57
57
|
s.add_development_dependency "rdoc"
|
58
58
|
else
|
59
|
-
s.add_dependency(%q<httpclient>, ["~> 2.8.2"])
|
59
|
+
s.add_dependency(%q<httpclient>, ["~> 2.8.2.4"])
|
60
60
|
s.add_dependency(%q<json>, [">= 1.5.1"])
|
61
61
|
end
|
62
62
|
else
|
63
|
-
s.add_dependency(%q<httpclient>, ["~> 2.8.2"])
|
63
|
+
s.add_dependency(%q<httpclient>, ["~> 2.8.2.4"])
|
64
64
|
s.add_dependency(%q<json>, [">= 1.5.1"])
|
65
65
|
end
|
66
66
|
end
|
data/lib/algolia/client.rb
CHANGED
data/lib/algolia/index.rb
CHANGED
@@ -208,9 +208,10 @@ module Algolia
|
|
208
208
|
# Get an object from this index
|
209
209
|
#
|
210
210
|
# @param objectID the unique identifier of the object to retrieve
|
211
|
-
# @param attributesToRetrieve (optional) if set, contains the list of attributes to retrieve as a string separated by ","
|
211
|
+
# @param attributesToRetrieve (optional) if set, contains the list of attributes to retrieve as an array of strings of a string separated by ","
|
212
212
|
#
|
213
213
|
def get_object(objectID, attributesToRetrieve = nil)
|
214
|
+
attributesToRetrieve = attributesToRetrieve.join(',') if attributesToRetrieve.is_a?(Array)
|
214
215
|
if attributesToRetrieve.nil?
|
215
216
|
client.get(Protocol.object_uri(name, objectID, nil), :read)
|
216
217
|
else
|
@@ -222,9 +223,16 @@ module Algolia
|
|
222
223
|
# Get a list of objects from this index
|
223
224
|
#
|
224
225
|
# @param objectIDs the array of unique identifier of the objects to retrieve
|
225
|
-
#
|
226
|
-
|
227
|
-
|
226
|
+
# @param attributesToRetrieve (optional) if set, contains the list of attributes to retrieve as an array of strings of a string separated by ","
|
227
|
+
#
|
228
|
+
def get_objects(objectIDs, attributesToRetrieve = nil)
|
229
|
+
attributesToRetrieve = attributesToRetrieve.join(',') if attributesToRetrieve.is_a?(Array)
|
230
|
+
requests = objectIDs.map do |objectID|
|
231
|
+
req = {:indexName => name, :objectID => objectID.to_s}
|
232
|
+
req[:attributesToRetrieve] = attributesToRetrieve unless attributesToRetrieve.nil?
|
233
|
+
req
|
234
|
+
end
|
235
|
+
client.post(Protocol.objects_uri, { :requests => requests }.to_json, :read)['results']
|
228
236
|
end
|
229
237
|
|
230
238
|
# Wait the publication of a task on the server.
|
@@ -555,6 +563,20 @@ module Algolia
|
|
555
563
|
res
|
556
564
|
end
|
557
565
|
|
566
|
+
# Search in facets
|
567
|
+
#
|
568
|
+
# @param facet Name of the facet to search. It must have been declared in the
|
569
|
+
# index's`attributesForFaceting` setting with the `searchable()` modifier.
|
570
|
+
# @param text Text to search for in the facet's values
|
571
|
+
# @param query An optional query to take extra search parameters into account.
|
572
|
+
# These parameters apply to index objects like in a regular search query.
|
573
|
+
# Only facet values contained in the matched objects will be returned.
|
574
|
+
def search_facet(facet, text, query = {})
|
575
|
+
params = query.clone
|
576
|
+
params['facetQuery'] = text
|
577
|
+
client.post(Protocol.search_facet_uri(name, facet), params.to_json)
|
578
|
+
end
|
579
|
+
|
558
580
|
# Perform a search with disjunctive facets generating as many queries as number of disjunctive facets
|
559
581
|
#
|
560
582
|
# @param query the query
|
@@ -675,17 +697,17 @@ module Algolia
|
|
675
697
|
# Delete a synonym
|
676
698
|
#
|
677
699
|
# @param objectID the synonym objectID
|
678
|
-
# @param
|
679
|
-
def delete_synonym(objectID,
|
680
|
-
client.delete("#{Protocol.synonym_uri(name, objectID)}?
|
700
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
701
|
+
def delete_synonym(objectID, forward_to_replicas = false)
|
702
|
+
client.delete("#{Protocol.synonym_uri(name, objectID)}?forwardToReplicas=#{forward_to_replicas}", :write)
|
681
703
|
end
|
682
704
|
|
683
705
|
# Delete a synonym and wait the end of indexing
|
684
706
|
#
|
685
707
|
# @param objectID the synonym objectID
|
686
|
-
# @param
|
687
|
-
def delete_synonym!(objectID,
|
688
|
-
res = delete_synonym(objectID,
|
708
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
709
|
+
def delete_synonym!(objectID, forward_to_replicas = false)
|
710
|
+
res = delete_synonym(objectID, forward_to_replicas)
|
689
711
|
wait_task(res["taskID"])
|
690
712
|
return res
|
691
713
|
end
|
@@ -694,34 +716,34 @@ module Algolia
|
|
694
716
|
#
|
695
717
|
# @param objectID the synonym objectID
|
696
718
|
# @param synonym the synonym
|
697
|
-
# @param
|
698
|
-
def save_synonym(objectID, synonym,
|
699
|
-
client.put("#{Protocol.synonym_uri(name, objectID)}?
|
719
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
720
|
+
def save_synonym(objectID, synonym, forward_to_replicas = false)
|
721
|
+
client.put("#{Protocol.synonym_uri(name, objectID)}?forwardToReplicas=#{forward_to_replicas}", synonym.to_json, :write)
|
700
722
|
end
|
701
723
|
|
702
724
|
# Save a synonym and wait the end of indexing
|
703
725
|
#
|
704
726
|
# @param objectID the synonym objectID
|
705
727
|
# @param synonym the synonym
|
706
|
-
# @param
|
707
|
-
def save_synonym!(objectID, synonym,
|
708
|
-
res = save_synonym(objectID, synonym,
|
728
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
729
|
+
def save_synonym!(objectID, synonym, forward_to_replicas = false)
|
730
|
+
res = save_synonym(objectID, synonym, forward_to_replicas)
|
709
731
|
wait_task(res["taskID"])
|
710
732
|
return res
|
711
733
|
end
|
712
734
|
|
713
735
|
# Clear all synonyms
|
714
736
|
#
|
715
|
-
# @param
|
716
|
-
def clear_synonyms(
|
717
|
-
client.post("#{Protocol.clear_synonyms_uri(name)}?
|
737
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
738
|
+
def clear_synonyms(forward_to_replicas = false)
|
739
|
+
client.post("#{Protocol.clear_synonyms_uri(name)}?forwardToReplicas=#{forward_to_replicas}", :write)
|
718
740
|
end
|
719
741
|
|
720
742
|
# Clear all synonyms and wait the end of indexing
|
721
743
|
#
|
722
|
-
# @param
|
723
|
-
def clear_synonyms!(
|
724
|
-
res = clear_synonyms(
|
744
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
745
|
+
def clear_synonyms!(forward_to_replicas = false)
|
746
|
+
res = clear_synonyms(forward_to_replicas)
|
725
747
|
wait_task(res["taskID"])
|
726
748
|
return res
|
727
749
|
end
|
@@ -729,19 +751,19 @@ module Algolia
|
|
729
751
|
# Add/Update an array of synonyms
|
730
752
|
#
|
731
753
|
# @param synonyms the array of synonyms to add/update
|
732
|
-
# @param
|
754
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
733
755
|
# @param replace_existing_synonyms should we replace the existing synonyms before adding the new ones
|
734
|
-
def batch_synonyms(synonyms,
|
735
|
-
client.post("#{Protocol.batch_synonyms_uri(name)}?
|
756
|
+
def batch_synonyms(synonyms, forward_to_replicas = false, replace_existing_synonyms = false)
|
757
|
+
client.post("#{Protocol.batch_synonyms_uri(name)}?forwardToReplicas=#{forward_to_replicas}&replaceExistingSynonyms=#{replace_existing_synonyms}", synonyms.to_json, :batch)
|
736
758
|
end
|
737
759
|
|
738
760
|
# Add/Update an array of synonyms and wait the end of indexing
|
739
761
|
#
|
740
762
|
# @param synonyms the array of synonyms to add/update
|
741
|
-
# @param
|
763
|
+
# @param forward_to_replicas should we forward the delete to replica indices
|
742
764
|
# @param replace_existing_synonyms should we replace the existing synonyms before adding the new ones
|
743
|
-
def batch_synonyms!(synonyms,
|
744
|
-
res = batch_synonyms(synonyms,
|
765
|
+
def batch_synonyms!(synonyms, forward_to_replicas = false, replace_existing_synonyms = false)
|
766
|
+
res = batch_synonyms(synonyms, forward_to_replicas, replace_existing_synonyms)
|
745
767
|
wait_task(res["taskID"])
|
746
768
|
return res
|
747
769
|
end
|
data/lib/algolia/protocol.rb
CHANGED
@@ -83,6 +83,10 @@ module Algolia
|
|
83
83
|
"#{index_uri(index)}/browse#{params}"
|
84
84
|
end
|
85
85
|
|
86
|
+
def Protocol.search_facet_uri(index, facet)
|
87
|
+
"#{index_uri(index)}/facets/#{facet}/query"
|
88
|
+
end
|
89
|
+
|
86
90
|
def Protocol.partial_object_uri(index, object_id, create_if_not_exits = true)
|
87
91
|
params = create_if_not_exits ? "" : "?createIfNotExists=false"
|
88
92
|
"#{index_uri(index)}/#{CGI.escape(object_id)}/partial#{params}"
|
data/lib/algolia/version.rb
CHANGED
data/spec/client_spec.rb
CHANGED
@@ -187,6 +187,26 @@ describe 'Client' do
|
|
187
187
|
objects.size.should eq(2)
|
188
188
|
end
|
189
189
|
|
190
|
+
it "should restrict attributesToRetrieve" do
|
191
|
+
@index.clear_index
|
192
|
+
@index.add_object({:firstname => "Robert", :lastname => "foo", :objectID => 1})
|
193
|
+
@index.add_object!({:firstname => "Robert2", :lastname => "bar", :objectID => 2})
|
194
|
+
objects = @index.get_objects([1, 2], ['firstname'])
|
195
|
+
objects.size.should eq(2)
|
196
|
+
objects[0].should eq({"firstname"=>"Robert", "objectID"=>"1"})
|
197
|
+
objects[1].should eq({"firstname"=>"Robert2", "objectID"=>"2"})
|
198
|
+
|
199
|
+
objects = @index.get_objects([1, 2], [:firstname])
|
200
|
+
objects.size.should eq(2)
|
201
|
+
objects[0].should eq({"firstname"=>"Robert", "objectID"=>"1"})
|
202
|
+
objects[1].should eq({"firstname"=>"Robert2", "objectID"=>"2"})
|
203
|
+
|
204
|
+
objects = @index.get_objects(["1", "2"], 'firstname,lastname')
|
205
|
+
objects.size.should eq(2)
|
206
|
+
objects[0].should eq({"firstname"=>"Robert", "lastname"=>"foo", "objectID"=>"1"})
|
207
|
+
objects[1].should eq({"firstname"=>"Robert2", "lastname"=>"bar", "objectID"=>"2"})
|
208
|
+
end
|
209
|
+
|
190
210
|
it "should delete the object" do
|
191
211
|
@index.clear
|
192
212
|
@index.add_object!({:firstname => "Robert"})
|
@@ -769,6 +789,64 @@ describe 'Client' do
|
|
769
789
|
res['results'][0]['params'].should be_a(String)
|
770
790
|
end
|
771
791
|
|
792
|
+
it 'should handle facet search' do
|
793
|
+
objects = {
|
794
|
+
:snoopy => {
|
795
|
+
:objectID => '1',
|
796
|
+
'name' => 'Snoopy',
|
797
|
+
:kind => ['dog', 'animal'],
|
798
|
+
:born => 1950,
|
799
|
+
:series => 'Peanuts'
|
800
|
+
},
|
801
|
+
:woodstock => {
|
802
|
+
:objectID => '2',
|
803
|
+
:name => 'Woodstock',
|
804
|
+
:kind => ['bird', 'animal'],
|
805
|
+
:born => 1960,
|
806
|
+
:series => 'Peanuts'
|
807
|
+
},
|
808
|
+
:charlie => {
|
809
|
+
:objectID => '3',
|
810
|
+
:name => 'Charlie Brown',
|
811
|
+
:kind => ['human'],
|
812
|
+
:born => 1950,
|
813
|
+
:series => 'Peanuts'
|
814
|
+
},
|
815
|
+
:hobbes => {
|
816
|
+
:objectID => '4',
|
817
|
+
:name => 'Hobbes',
|
818
|
+
:kind => ['tiger', 'animal', 'teddy'],
|
819
|
+
:born => 1985,
|
820
|
+
:series => 'Calvin & Hobbes'
|
821
|
+
},
|
822
|
+
:calvin => {
|
823
|
+
:objectID => '5',
|
824
|
+
:name => 'Calvin',
|
825
|
+
:kind => ['human'],
|
826
|
+
:born => 1985,
|
827
|
+
:series => 'Calvin & Hobbes'
|
828
|
+
}
|
829
|
+
}
|
830
|
+
|
831
|
+
index = Algolia::Index.new(safe_index_name('test_facet_search'))
|
832
|
+
index.set_settings({
|
833
|
+
:attributesForFaceting => [
|
834
|
+
'searchable(series)',
|
835
|
+
'kind'
|
836
|
+
]
|
837
|
+
})
|
838
|
+
index.add_objects! objects.values
|
839
|
+
|
840
|
+
query = {
|
841
|
+
:facetFilters => ['kind:animal'],
|
842
|
+
:numericFilters => ['born >= 1955']
|
843
|
+
}
|
844
|
+
answer = index.search_facet 'series', 'Peanutz', query
|
845
|
+
expect(answer['facetHits'].size).to eq(1)
|
846
|
+
expect(answer['facetHits'].first['value']).to eq('Peanuts')
|
847
|
+
expect(answer['facetHits'].first['count']).to eq(1)
|
848
|
+
end
|
849
|
+
|
772
850
|
it 'should handle disjunctive faceting' do
|
773
851
|
index = Algolia::Index.new(safe_index_name("test_hotels"))
|
774
852
|
index.set_settings :attributesForFacetting => ['city', 'stars', 'facilities']
|
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.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-10-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: httpclient
|
@@ -16,14 +16,14 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 2.8.2
|
19
|
+
version: 2.8.2.4
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 2.8.2
|
26
|
+
version: 2.8.2.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: json
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|