algolia 2.1.1 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.circleci/config.yml +1 -1
- data/CHANGELOG.md +6 -1
- data/README.md +1 -1
- data/lib/algolia/config/recommend_config.rb +6 -0
- data/lib/algolia/recommend_client.rb +134 -0
- data/lib/algolia/search_client.rb +1 -0
- data/lib/algolia/version.rb +1 -1
- data/lib/algolia.rb +2 -0
- data/test/algolia/integration/mocks/mock_requester.rb +13 -11
- data/test/algolia/integration/recommend_client_test.rb +70 -0
- data/test/test_helper.rb +16 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 799e36b37cca18189b15d27f6b755904ef5c9707906258cfc3af51691a9af3a6
|
4
|
+
data.tar.gz: a4235ea4599c928ac96eb9fc1243b8ccb915d2636d30282ff20d792bc7b1b174
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bff81541d4dd4392598eb229ee5e854e352988daa7af4892c07e94cd8574b0dab02e1d0a54aba710370775f521ef0338399a5c7876659b2be75d21e083eb4bfc
|
7
|
+
data.tar.gz: 6549f6d062a2cecbe6521d7961563917d0a9ea9d660991f644ae00b0ef7772557eae5c416efd633544d81cac3d16a94ed5ba3633297710d553a571c85d746da7
|
data/.circleci/config.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
# ChangeLog
|
2
2
|
|
3
|
-
## [Unreleased](https://github.com/algolia/algoliasearch-client-ruby/compare/2.
|
3
|
+
## [Unreleased](https://github.com/algolia/algoliasearch-client-ruby/compare/2.2.0..master)
|
4
|
+
|
5
|
+
## [2.2.0](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.1...2.2.0) (2021-11-08)
|
6
|
+
### Added
|
7
|
+
- Added RecommendClient ([`#466`](https://github.com/algolia/algoliasearch-client-ruby/pull/466))
|
8
|
+
- Added `search` alias for `multiple_queries` ([`#457`](https://github.com/algolia/algoliasearch-client-ruby/pull/457))
|
4
9
|
|
5
10
|
## [2.1.1](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.0...2.1.1) (2021-05-27)
|
6
11
|
|
data/README.md
CHANGED
@@ -41,7 +41,7 @@ Then, create objects on your index:
|
|
41
41
|
client = Algolia::Search::Client.create('YourApplicationID', 'YourAPIKey')
|
42
42
|
index = client.init_index('your_index_name')
|
43
43
|
|
44
|
-
index.save_objects([objectID: 1, name: 'Foo'])
|
44
|
+
index.save_objects([{objectID: 1, name: 'Foo'}])
|
45
45
|
```
|
46
46
|
|
47
47
|
Finally, you may begin searching a object using the `search` method:
|
@@ -0,0 +1,134 @@
|
|
1
|
+
module Algolia
|
2
|
+
module Recommend
|
3
|
+
class Model
|
4
|
+
BOUGHT_TOGETHER = 'bought-together'
|
5
|
+
RELATED_PRODUCTS = 'related-products'
|
6
|
+
end
|
7
|
+
|
8
|
+
class Client
|
9
|
+
include Helpers
|
10
|
+
|
11
|
+
# Initializes the Recommend client
|
12
|
+
#
|
13
|
+
# @param recommend_config [Recommend::Config] a Recommend::Config object which contains your APP_ID and API_KEY
|
14
|
+
# @option adapter [Object] adapter object used for the connection
|
15
|
+
# @option logger [Object]
|
16
|
+
# @option http_requester [Object] http_requester object used for the connection
|
17
|
+
#
|
18
|
+
def initialize(recommend_config, opts = {})
|
19
|
+
@config = recommend_config
|
20
|
+
adapter = opts[:adapter] || Defaults::ADAPTER
|
21
|
+
logger = opts[:logger] || LoggerHelper.create('debug.log')
|
22
|
+
requester = opts[:http_requester] || Defaults::REQUESTER_CLASS.new(adapter, logger)
|
23
|
+
@transporter = Transport::Transport.new(@config, requester)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Create a new client providing only app ID and API key
|
27
|
+
#
|
28
|
+
# @param app_id [String] Algolia application ID
|
29
|
+
# @param api_key [String] Algolia API key
|
30
|
+
#
|
31
|
+
# @return self
|
32
|
+
#
|
33
|
+
def self.create(app_id, api_key)
|
34
|
+
config = Recommend::Config.new(application_id: app_id, api_key: api_key)
|
35
|
+
create_with_config(config)
|
36
|
+
end
|
37
|
+
|
38
|
+
# Create a new client providing only an Recommend::Config object
|
39
|
+
#
|
40
|
+
# @param config [Recommend::Config]
|
41
|
+
#
|
42
|
+
# @return self
|
43
|
+
#
|
44
|
+
def self.create_with_config(config)
|
45
|
+
new(config)
|
46
|
+
end
|
47
|
+
|
48
|
+
# Get recommendation for the given queries
|
49
|
+
#
|
50
|
+
# @param requests [Array<Hash>] the queries to retrieve recommendations for
|
51
|
+
# @param opts [Hash] extra parameters to send with your request
|
52
|
+
#
|
53
|
+
# @return [Hash]
|
54
|
+
#
|
55
|
+
def get_recommendations(requests, opts = {})
|
56
|
+
@transporter.write(
|
57
|
+
:POST,
|
58
|
+
'/1/indexes/*/recommendations',
|
59
|
+
{ requests: format_recommendation_requests(symbolize_all(requests)) },
|
60
|
+
opts
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Get related products for the given requests
|
65
|
+
#
|
66
|
+
# @param requests [Array<Hash>] the requests to get related products for
|
67
|
+
# @param opts [Hash] extra parameters to send with your request
|
68
|
+
#
|
69
|
+
# @return [Hash]
|
70
|
+
#
|
71
|
+
def get_related_products(requests, opts = {})
|
72
|
+
get_recommendations(
|
73
|
+
set_request_models(symbolize_all(requests), Model::RELATED_PRODUCTS),
|
74
|
+
opts
|
75
|
+
)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Get frequently bought together items for the given requests
|
79
|
+
#
|
80
|
+
# @param requests [Array<Hash>] the requests to get frequently bought together items for
|
81
|
+
# @param opts [Hash] extra parameters to send with your request
|
82
|
+
#
|
83
|
+
# @return [Hash]
|
84
|
+
#
|
85
|
+
def get_frequently_bought_together(requests, opts = {})
|
86
|
+
get_recommendations(
|
87
|
+
set_request_models(symbolize_all(requests), Model::BOUGHT_TOGETHER),
|
88
|
+
opts
|
89
|
+
)
|
90
|
+
end
|
91
|
+
|
92
|
+
private
|
93
|
+
|
94
|
+
# Symbolize all hashes in an array
|
95
|
+
#
|
96
|
+
# @param hash_array [Array<Hash<String|Symbol, any>>] the hashes to symbolize
|
97
|
+
#
|
98
|
+
# @return [Array<Hash<Symbol, any>>]
|
99
|
+
#
|
100
|
+
def symbolize_all(hash_array)
|
101
|
+
hash_array.map { |q| symbolize_hash(q) }
|
102
|
+
end
|
103
|
+
|
104
|
+
# Format the recommendation requests
|
105
|
+
#
|
106
|
+
# @param requests [Array<Hash>] the requests to retrieve recommendations for
|
107
|
+
#
|
108
|
+
# @return [Array<Hash>]
|
109
|
+
#
|
110
|
+
def format_recommendation_requests(requests)
|
111
|
+
requests.map do |request|
|
112
|
+
request[:threshold] = 0 unless request[:threshold].is_a? Numeric
|
113
|
+
request.delete(:fallbackParameters) if request[:model] == Model::BOUGHT_TOGETHER
|
114
|
+
|
115
|
+
request
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
# Force the requests to target a specific model
|
120
|
+
#
|
121
|
+
# @param requests [Array<Hash>] the requests to change
|
122
|
+
# @param model [String] the model to enforce
|
123
|
+
#
|
124
|
+
# @return [Array<Hash>]
|
125
|
+
#
|
126
|
+
def set_request_models(requests, model)
|
127
|
+
requests.map do |query|
|
128
|
+
query[:model] = model
|
129
|
+
query
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
@@ -480,6 +480,7 @@ module Algolia
|
|
480
480
|
def multiple_queries(queries, opts = {})
|
481
481
|
@transporter.read(:POST, '/1/indexes/*/queries', { requests: queries }, opts)
|
482
482
|
end
|
483
|
+
alias_method :search, :multiple_queries
|
483
484
|
|
484
485
|
# # # # # # # # # # # # # # # # # # # # #
|
485
486
|
# MCM METHODS
|
data/lib/algolia/version.rb
CHANGED
data/lib/algolia.rb
CHANGED
@@ -7,6 +7,7 @@ require 'algolia/config/base_config'
|
|
7
7
|
require 'algolia/config/search_config'
|
8
8
|
require 'algolia/config/analytics_config'
|
9
9
|
require 'algolia/config/insights_config'
|
10
|
+
require 'algolia/config/recommend_config'
|
10
11
|
require 'algolia/config/recommendation_config'
|
11
12
|
require 'algolia/enums/call_type'
|
12
13
|
require 'algolia/enums/retry_outcome_type'
|
@@ -33,6 +34,7 @@ require 'algolia/account_client'
|
|
33
34
|
require 'algolia/search_client'
|
34
35
|
require 'algolia/analytics_client'
|
35
36
|
require 'algolia/insights_client'
|
37
|
+
require 'algolia/recommend_client'
|
36
38
|
require 'algolia/recommendation_client'
|
37
39
|
require 'algolia/error'
|
38
40
|
require 'algolia/search_index'
|
@@ -1,25 +1,27 @@
|
|
1
1
|
class MockRequester
|
2
|
+
attr_accessor :requests
|
2
3
|
def initialize
|
3
4
|
@connection = nil
|
5
|
+
@requests = []
|
4
6
|
end
|
5
7
|
|
6
|
-
def send_request(host, method, path,
|
7
|
-
|
8
|
-
response = {
|
9
|
-
connection: connection,
|
8
|
+
def send_request(host, method, path, body, headers, timeout, connect_timeout)
|
9
|
+
request = {
|
10
10
|
host: host,
|
11
|
+
method: method,
|
11
12
|
path: path,
|
13
|
+
body: body,
|
12
14
|
headers: headers,
|
13
|
-
|
14
|
-
|
15
|
-
body: '{"hits":[],"nbHits":0,"page":0,"nbPages":1,"hitsPerPage":20,"exhaustiveNbHits":true,"query":"test","params":"query=test","processingTimeMS":1}',
|
16
|
-
success: true
|
15
|
+
timeout: timeout,
|
16
|
+
connect_timeout: connect_timeout
|
17
17
|
}
|
18
18
|
|
19
|
+
@requests.push(request)
|
20
|
+
|
19
21
|
Algolia::Http::Response.new(
|
20
|
-
status:
|
21
|
-
body:
|
22
|
-
headers:
|
22
|
+
status: 200,
|
23
|
+
body: '{"hits": []}',
|
24
|
+
headers: {}
|
23
25
|
)
|
24
26
|
end
|
25
27
|
|
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
require_relative 'base_test'
|
3
|
+
|
4
|
+
class RecommendClientTest < BaseTest
|
5
|
+
describe 'Recommendations' do
|
6
|
+
def test_get_recommendations
|
7
|
+
requester = MockRequester.new
|
8
|
+
client = Algolia::Recommend::Client.new(@@search_config, http_requester: requester)
|
9
|
+
|
10
|
+
# It correctly formats queries using the 'bought-together' model
|
11
|
+
client.get_recommendations([{ indexName: 'products', objectID: 'B018APC4LE', model: Algolia::Recommend::Model::BOUGHT_TOGETHER }])
|
12
|
+
|
13
|
+
# It correctly formats queries using the 'related-products' model
|
14
|
+
client.get_recommendations([{ indexName: 'products', objectID: 'B018APC4LE', model: Algolia::Recommend::Model::RELATED_PRODUCTS }])
|
15
|
+
|
16
|
+
# It correctly formats multiple queries.
|
17
|
+
client.get_recommendations(
|
18
|
+
[
|
19
|
+
{ indexName: 'products', objectID: 'B018APC4LE-1', model: Algolia::Recommend::Model::RELATED_PRODUCTS, threshold: 0 },
|
20
|
+
{ indexName: 'products', objectID: 'B018APC4LE-2', model: Algolia::Recommend::Model::RELATED_PRODUCTS, threshold: 0 }
|
21
|
+
]
|
22
|
+
)
|
23
|
+
|
24
|
+
# It resets the threshold to 0 if it's not numeric.
|
25
|
+
client.get_recommendations([{ indexName: 'products', objectID: 'B018APC4LE', model: Algolia::Recommend::Model::BOUGHT_TOGETHER, threshold: nil }])
|
26
|
+
|
27
|
+
# It passes the threshold correctly if it's numeric.
|
28
|
+
client.get_recommendations([{ indexName: 'products', objectID: 'B018APC4LE', model: Algolia::Recommend::Model::BOUGHT_TOGETHER, threshold: 42 }])
|
29
|
+
|
30
|
+
assert_requests(
|
31
|
+
requester,
|
32
|
+
[
|
33
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"bought-together","threshold":0}]}' },
|
34
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"related-products","threshold":0}]}' },
|
35
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE-1","model":"related-products","threshold":0},{"indexName":"products","objectID":"B018APC4LE-2","model":"related-products","threshold":0}]}' },
|
36
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"bought-together","threshold":0}]}' },
|
37
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"bought-together","threshold":42}]}' }
|
38
|
+
]
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
def test_get_related_products
|
43
|
+
requester = MockRequester.new
|
44
|
+
client = Algolia::Recommend::Client.new(@@search_config, http_requester: requester)
|
45
|
+
|
46
|
+
client.get_related_products([{ indexName: 'products', objectID: 'B018APC4LE' }])
|
47
|
+
|
48
|
+
assert_requests(
|
49
|
+
requester,
|
50
|
+
[{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"related-products","threshold":0}]}' }]
|
51
|
+
)
|
52
|
+
end
|
53
|
+
|
54
|
+
def test_get_frequently_bought_together
|
55
|
+
requester = MockRequester.new
|
56
|
+
client = Algolia::Recommend::Client.new(@@search_config, http_requester: requester)
|
57
|
+
|
58
|
+
client.get_frequently_bought_together([{ indexName: 'products', objectID: 'B018APC4LE' }])
|
59
|
+
client.get_frequently_bought_together([{ indexName: 'products', objectID: 'B018APC4LE', fallbackParameters: {} }])
|
60
|
+
|
61
|
+
assert_requests(
|
62
|
+
requester,
|
63
|
+
[
|
64
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"bought-together","threshold":0}]}' },
|
65
|
+
{ method: :post, path: '/1/indexes/*/recommendations', body: '{"requests":[{"indexName":"products","objectID":"B018APC4LE","model":"bought-together","threshold":0}]}' }
|
66
|
+
]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -28,6 +28,22 @@ class Minitest::Test
|
|
28
28
|
@@search_client = Algolia::Search::Client.new(@@search_config)
|
29
29
|
end
|
30
30
|
|
31
|
+
def assert_requests(requester, requests)
|
32
|
+
refute_empty requests
|
33
|
+
refute_nil requester
|
34
|
+
|
35
|
+
actual_requests = requester.requests
|
36
|
+
assert_equal requests.size, actual_requests.size
|
37
|
+
|
38
|
+
requests.each_with_index do |expected_request, i|
|
39
|
+
request = actual_requests[i]
|
40
|
+
|
41
|
+
assert_equal(expected_request[:body], request[:body])
|
42
|
+
assert_equal(expected_request[:method], request[:method])
|
43
|
+
assert_equal(expected_request[:path], request[:path])
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
31
47
|
def check_environment_variables
|
32
48
|
raise Algolia::AlgoliaError, 'ALGOLIA_APPLICATION_ID_1 must be defined' if ENV['ALGOLIA_APPLICATION_ID_1'].to_s.strip.empty?
|
33
49
|
raise Algolia::AlgoliaError, 'ALGOLIA_ADMIN_KEY_1 must be defined' if ENV['ALGOLIA_ADMIN_KEY_1'].to_s.strip.empty?
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: algolia
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Algolia
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-11-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -218,6 +218,7 @@ files:
|
|
218
218
|
- lib/algolia/config/analytics_config.rb
|
219
219
|
- lib/algolia/config/base_config.rb
|
220
220
|
- lib/algolia/config/insights_config.rb
|
221
|
+
- lib/algolia/config/recommend_config.rb
|
221
222
|
- lib/algolia/config/recommendation_config.rb
|
222
223
|
- lib/algolia/config/search_config.rb
|
223
224
|
- lib/algolia/defaults.rb
|
@@ -234,6 +235,7 @@ files:
|
|
234
235
|
- lib/algolia/iterators/rule_iterator.rb
|
235
236
|
- lib/algolia/iterators/synonym_iterator.rb
|
236
237
|
- lib/algolia/logger_helper.rb
|
238
|
+
- lib/algolia/recommend_client.rb
|
237
239
|
- lib/algolia/recommendation_client.rb
|
238
240
|
- lib/algolia/responses/add_api_key_response.rb
|
239
241
|
- lib/algolia/responses/base_response.rb
|
@@ -274,6 +276,7 @@ files:
|
|
274
276
|
- test/algolia/integration/base_test.rb
|
275
277
|
- test/algolia/integration/insights_client_test.rb
|
276
278
|
- test/algolia/integration/mocks/mock_requester.rb
|
279
|
+
- test/algolia/integration/recommend_client_test.rb
|
277
280
|
- test/algolia/integration/recommendation_client_test.rb
|
278
281
|
- test/algolia/integration/search_client_test.rb
|
279
282
|
- test/algolia/integration/search_index_test.rb
|
@@ -315,6 +318,7 @@ test_files:
|
|
315
318
|
- test/algolia/integration/base_test.rb
|
316
319
|
- test/algolia/integration/insights_client_test.rb
|
317
320
|
- test/algolia/integration/mocks/mock_requester.rb
|
321
|
+
- test/algolia/integration/recommend_client_test.rb
|
318
322
|
- test/algolia/integration/recommendation_client_test.rb
|
319
323
|
- test/algolia/integration/search_client_test.rb
|
320
324
|
- test/algolia/integration/search_index_test.rb
|