algolia 2.0.3 → 2.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.circleci/config.yml +10 -1
- data/CHANGELOG.md +28 -1
- data/CONTRIBUTING.MD +184 -0
- data/README.md +1 -5
- data/lib/algolia/config/personalization_config.rb +20 -0
- data/lib/algolia/config/recommend_config.rb +6 -0
- data/lib/algolia/config/recommendation_config.rb +2 -15
- data/lib/algolia/helpers.rb +49 -0
- data/lib/algolia/http/http_requester.rb +4 -4
- data/lib/algolia/personalization_client.rb +60 -0
- data/lib/algolia/recommend_client.rb +134 -0
- data/lib/algolia/recommendation_client.rb +2 -55
- data/lib/algolia/responses/dictionary_response.rb +33 -0
- data/lib/algolia/search_client.rb +177 -3
- data/lib/algolia/search_index.rb +9 -50
- data/lib/algolia/version.rb +1 -1
- data/lib/algolia.rb +5 -0
- data/test/algolia/integration/analytics_client_test.rb +6 -2
- data/test/algolia/integration/mocks/mock_requester.rb +13 -11
- data/test/algolia/integration/personalization_client_test.rb +30 -0
- data/test/algolia/integration/recommend_client_test.rb +70 -0
- data/test/algolia/integration/search_client_test.rb +107 -12
- data/test/algolia/integration/search_index_test.rb +3 -0
- data/test/test_helper.rb +28 -0
- metadata +13 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6f4bd19a2458e131aa5492ad5aefb851d27f756e59e483b54e4bfd1c385fa851
|
4
|
+
data.tar.gz: 83fe8e73abb8ddff9aa52b8492a78d3fec616d598e56c2c79f6e6b57d678f457
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9b45bc8ba4e45089de2ce90cf99e20cef6067c59738a88779d03fbe3c0bd88233304cd0296755cb029cb5610281b47dd09a69beb86034f7ba833bea2f6522501
|
7
|
+
data.tar.gz: e93d44ea2bfc529248f59996fcb72cb03cd3c578d847e6d6f6f1ec3c42552bebcf16007ff60e5a797c789ed9c5bf73436e8a807f7db581e1cdb5473331746ea5
|
data/.circleci/config.yml
CHANGED
@@ -23,6 +23,13 @@ aliases:
|
|
23
23
|
name: Run linting tool
|
24
24
|
command: bundle exec rake rubocop
|
25
25
|
|
26
|
+
- &credentials
|
27
|
+
name: Retrieve temporary Algolia credentials if needed
|
28
|
+
command: |
|
29
|
+
if [ "$CIRCLE_PR_REPONAME" ]; then
|
30
|
+
curl -s https://algoliasearch-client-keygen.herokuapp.com | sh >> $BASH_ENV
|
31
|
+
fi
|
32
|
+
|
26
33
|
- &run_tests
|
27
34
|
name: Run unit and integration tests
|
28
35
|
command: |
|
@@ -73,6 +80,7 @@ jobs:
|
|
73
80
|
- restore_cache: *restore_cache
|
74
81
|
- run: *install_bundler
|
75
82
|
- save_cache: *save_cache
|
83
|
+
- run: *credentials
|
76
84
|
- run: *run_tests
|
77
85
|
|
78
86
|
test_jruby:
|
@@ -88,6 +96,7 @@ jobs:
|
|
88
96
|
- restore_cache: *restore_cache
|
89
97
|
- run: *install_bundler
|
90
98
|
- save_cache: *save_cache
|
99
|
+
- run: *credentials
|
91
100
|
- run: *run_tests
|
92
101
|
|
93
102
|
release:
|
@@ -122,7 +131,7 @@ workflows:
|
|
122
131
|
- test_ruby:
|
123
132
|
matrix:
|
124
133
|
parameters:
|
125
|
-
version: ['2.2', '2.3', '2.4', '2.5', '2.6', '2.7']
|
134
|
+
version: ['2.2', '2.3', '2.4', '2.5', '2.6', '2.7', '3.0']
|
126
135
|
filters:
|
127
136
|
tags:
|
128
137
|
only: /.*/
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,33 @@
|
|
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.1..master)
|
4
|
+
|
5
|
+
## [2.2.1](https://github.com/algolia/algoliasearch-client-ruby/compare/2.2.0...2.2.1) (2021-11-12)
|
6
|
+
### Chore
|
7
|
+
- Deprecated `RecommendationClient` in favor of `PersonalizationClient` ([`#461`](https://github.com/algolia/algoliasearch-client-ruby/pull/461))
|
8
|
+
|
9
|
+
## [2.2.0](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.1...2.2.0) (2021-11-08)
|
10
|
+
### Added
|
11
|
+
- Added RecommendClient ([`#466`](https://github.com/algolia/algoliasearch-client-ruby/pull/466))
|
12
|
+
- Added `search` alias for `multiple_queries` ([`#457`](https://github.com/algolia/algoliasearch-client-ruby/pull/457))
|
13
|
+
|
14
|
+
## [2.1.1](https://github.com/algolia/algoliasearch-client-ruby/compare/2.1.0...2.1.1) (2021-05-27)
|
15
|
+
|
16
|
+
### Fix
|
17
|
+
- Bug with read/write nodes caching ([`#455`](https://github.com/algolia/algoliasearch-client-ruby/pull/455))
|
18
|
+
|
19
|
+
## [2.1.0](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.4...2.1.0) (2021-03-30)
|
20
|
+
|
21
|
+
### Feat
|
22
|
+
- Custom dictionaries methods
|
23
|
+
|
24
|
+
### Fix
|
25
|
+
- The parameter `forwardToReplicas` should be handled independently in the `set_settings` method
|
26
|
+
|
27
|
+
## [2.0.4](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.3...2.0.4) (2021-01-05)
|
28
|
+
|
29
|
+
### Fix
|
30
|
+
- `app_api_key`: send opts with waitable method
|
4
31
|
|
5
32
|
## [2.0.3](https://github.com/algolia/algoliasearch-client-ruby/compare/2.0.2...2.0.3) (2020-11-24)
|
6
33
|
|
data/CONTRIBUTING.MD
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
<p align="center">
|
2
|
+
<a href="https://www.algolia.com">
|
3
|
+
<img alt="Algolia for Ruby" src="https://raw.githubusercontent.com/algolia/algoliasearch-client-common/master/banners/ruby.png" >
|
4
|
+
</a>
|
5
|
+
</p>
|
6
|
+
|
7
|
+
Hello and welcome to the contributing guide for algolia gem. Thanks for considering participating in our project 🙇
|
8
|
+
|
9
|
+
If this guide does not contain what you are looking for and thus prevents you from contributing, don't hesitate to leave a message on the [community forum](https://discourse.algolia.com/) or to [open an issue](https://github.com/algolia/algoliasearch-client-ruby/issues).
|
10
|
+
|
11
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN TocDown TO UPDATE -->
|
12
|
+
<!-- TocDown Begin -->
|
13
|
+
* [Reporting an issue](#reporting-an-issue)
|
14
|
+
* [The code contribution process](#the-code-contribution-process)
|
15
|
+
* [Commit conventions](#commit-conventions)
|
16
|
+
* [Branch organization](#branch-organization)
|
17
|
+
* [Requirements](#requirements)
|
18
|
+
* [Code structure](#code-structure)
|
19
|
+
* [The source algolia folder](#the-source-algolia-folder)
|
20
|
+
* [Tests](#tests)
|
21
|
+
* [Linting](#linting)
|
22
|
+
<!-- TocDown End -->
|
23
|
+
|
24
|
+
## Reporting an issue
|
25
|
+
|
26
|
+
Opening an issue is very effective way to contribute because other users might also be impacted. We'll make sure to fix it quickly if it's technically feasible and doesn't have important side effects for other users.
|
27
|
+
|
28
|
+
Before reporting an issue, first check that there is not an already open issue for the same topic using the [issues page](https://github.com/algolia/algoliasearch-client-ruby/issues). Don't hesitate to thumb up an issue that corresponds to the problem you have.
|
29
|
+
|
30
|
+
It would be very helpful if you're able to add a test case that reproduces the issue. This could help us solve the issue faster.
|
31
|
+
|
32
|
+
## The code contribution process
|
33
|
+
|
34
|
+
The algolia gem is developed in Ruby ≥ 2.2.
|
35
|
+
|
36
|
+
For any code contribution, you need to:
|
37
|
+
|
38
|
+
- Fork and clone the project
|
39
|
+
- Create a new branch for what you want to solve (fix/_issue-number_, feat/_name-of-the-feature_)
|
40
|
+
- Make your changes
|
41
|
+
- Open a pull request
|
42
|
+
|
43
|
+
Depending on what you're working on, you might consider different [base branches](#branch-organization).
|
44
|
+
|
45
|
+
Then:
|
46
|
+
|
47
|
+
- Peer review of the pull request (by at least one of the core contributors)
|
48
|
+
- Automatic checks ([tests](#tests), [commits](#commit-conventions), [linters](#linting))
|
49
|
+
- When everything is green, one of the core contributors will merge your contribution 🚀
|
50
|
+
|
51
|
+
## Commit conventions
|
52
|
+
|
53
|
+
This project follows the [conventional changelog](https://conventionalcommits.org/) approach. This means that all commit messages should be formatted using the following scheme:
|
54
|
+
|
55
|
+
```
|
56
|
+
type(scope): description
|
57
|
+
```
|
58
|
+
|
59
|
+
In most cases, we use the following types:
|
60
|
+
|
61
|
+
- `fix`: for any resolution of an issue (identified or not)
|
62
|
+
- `feat`: for any new feature
|
63
|
+
- `refactor`: for any code change that neither adds a feature nor fixes an issue
|
64
|
+
- `docs`: for any documentation change or addition
|
65
|
+
- `chore`: for anything that is not related to the library itself (doc, tooling)
|
66
|
+
|
67
|
+
Even though the scope is optional, we try to fill it in as it helps us better understand the impact of a change. We either use the name of the widget/connector/component impacted or we use impact topic (e.g. `docs`, `tooling`, `deps`, `ci`).
|
68
|
+
|
69
|
+
Finally, if your work is based on an issue on GitHub, please fill in the dedicated line in the PR template (read "[Closing issues using keywords](https://help.github.com/en/articles/closing-issues-using-keywords)").
|
70
|
+
|
71
|
+
Some examples of valid commit messages (used as first lines):
|
72
|
+
|
73
|
+
> - feat(account-client): add method XXX
|
74
|
+
> - chore(deps): update dependency XXX to v3.0.7
|
75
|
+
> - fix(search_user_ids): rename parameter clusterName
|
76
|
+
> - chore: reword contributions guides
|
77
|
+
|
78
|
+
## Branch organization
|
79
|
+
|
80
|
+
The project is based on the classic GitHub flow:
|
81
|
+
|
82
|
+
- `master` for the current version being worked on – Pull requests for bugs and feature related to the current major version should be created against this branch
|
83
|
+
- `vX` for each major version (`X` being a number) – Pull requests for critical bug fixes should be created against this branch
|
84
|
+
|
85
|
+
Most of the time, your pull requests should target the `master` branch.
|
86
|
+
|
87
|
+
_Note that no new features will be developed or backported for the `vX` branches._
|
88
|
+
|
89
|
+
## Requirements
|
90
|
+
|
91
|
+
To run this project, you will need:
|
92
|
+
|
93
|
+
- Ruby ≥ 2.2
|
94
|
+
- [Bundler](https://bundler.io/)
|
95
|
+
|
96
|
+
## Use the Dockerfile
|
97
|
+
|
98
|
+
If you want to contribute to this project without installing all its dependencies, you can use our Docker image.
|
99
|
+
Please check our [dedicated guide](DOCKER_README.MD) to learn more.
|
100
|
+
|
101
|
+
## Code structure
|
102
|
+
|
103
|
+
Here are the main files and folders of the project
|
104
|
+
|
105
|
+
```
|
106
|
+
▸ lib/algolia/ << standalone clients and helpers classes
|
107
|
+
▸ lib/test/ << gathers the unit and integration tests
|
108
|
+
.rubocop.yml << contains the rule used for the linter
|
109
|
+
algolia.gemspec << gemspec file
|
110
|
+
CHANGELOG.md << changelog file
|
111
|
+
CONTRIBUTING.md << this file
|
112
|
+
Gemfile << dependencies needed to run the project locally
|
113
|
+
Rakefile << defines the different tasks to lint/test the project
|
114
|
+
README.md << the introduction of the project
|
115
|
+
```
|
116
|
+
|
117
|
+
### The lib/algolia folder
|
118
|
+
|
119
|
+
```
|
120
|
+
▸ lib/algolia/
|
121
|
+
▸ config/ << the configurations associated with each clients
|
122
|
+
▸ enums/ << enumerables used accross the lib
|
123
|
+
▸ http/ << the http layer logic
|
124
|
+
▸ iterators/ << the iterators used for the browsing methods
|
125
|
+
▸ responses/ << the waitable responses
|
126
|
+
▸ transport/ << the transport layer logic
|
127
|
+
```
|
128
|
+
|
129
|
+
## Tests
|
130
|
+
|
131
|
+
Our unit and integration tests are written with [Minitest](https://github.com/seattlerb/minitest), in the `test` syntax.
|
132
|
+
|
133
|
+
To run all the tests at once:
|
134
|
+
|
135
|
+
```sh
|
136
|
+
bundle exec rake test:all
|
137
|
+
```
|
138
|
+
|
139
|
+
To run only the unit tests:
|
140
|
+
|
141
|
+
```sh
|
142
|
+
bundle exec rake test:unit
|
143
|
+
```
|
144
|
+
|
145
|
+
To run only the integration tests:
|
146
|
+
|
147
|
+
```sh
|
148
|
+
bundle exec rake test:integration
|
149
|
+
```
|
150
|
+
|
151
|
+
We ask that for each fix or feature submitted, you add at least one test demonstrating its behaviour. As you will need to use your own Algolia credentials to run them, we advise you to keep them short and use a small dataset, as well as using a mock requester anytime it's possible. If you encounter huge data overload because of testing, please reach out to [our support team](support@algolia.com).
|
152
|
+
|
153
|
+
## Linting
|
154
|
+
|
155
|
+
Linters help us maintain a consistent code base.
|
156
|
+
|
157
|
+
If your editor support them, then you will see the errors directly there. You can also run them using your command line:
|
158
|
+
|
159
|
+
```sh
|
160
|
+
rake rubocop
|
161
|
+
```
|
162
|
+
|
163
|
+
However, we recommend that you use in your workflow pre-commit hooks, to avoid submitting code that might not pass the linting task setup in the CI. To use them,
|
164
|
+
first download the gem `git-precommit`
|
165
|
+
|
166
|
+
```sh
|
167
|
+
gem install git-precommit
|
168
|
+
```
|
169
|
+
|
170
|
+
Then copy-paste the following content in a file called `pre-commit` in `.git/hooks/`
|
171
|
+
|
172
|
+
```sh
|
173
|
+
#!/usr/bin/env sh
|
174
|
+
|
175
|
+
function unstaged_changes {
|
176
|
+
! git diff --quiet
|
177
|
+
}
|
178
|
+
|
179
|
+
if unstaged_changes; then
|
180
|
+
git stash save --keep-index "Performing partial commit against `git rev-parse HEAD`"
|
181
|
+
fi
|
182
|
+
|
183
|
+
exec time bundle exec rake precommit
|
184
|
+
```
|
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:
|
@@ -59,10 +59,6 @@ Encountering an issue? Before reaching out to support, we recommend heading to o
|
|
59
59
|
|
60
60
|
If you were using the v1 and wish to update to v2, please follow our [Upgrade Guide](upgrade_guide.md)
|
61
61
|
|
62
|
-
## Use the Dockerfile
|
63
|
-
|
64
|
-
If you want to contribute to this project without installing all its dependencies, you can use our Docker image. Please check our [dedicated guide](DOCKER_README.MD) to learn more.
|
65
|
-
|
66
62
|
## 📄 License
|
67
63
|
|
68
64
|
Algolia Ruby API Client is an open-sourced software licensed under the [MIT license](LICENSE.md).
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Algolia
|
2
|
+
module Personalization
|
3
|
+
class Config < BaseConfig
|
4
|
+
attr_accessor :region, :default_hosts
|
5
|
+
|
6
|
+
# Initialize a config
|
7
|
+
#
|
8
|
+
# @option options [String] :application_id
|
9
|
+
# @option options [String] :api_key
|
10
|
+
# @option options [String] :region
|
11
|
+
#
|
12
|
+
def initialize(opts = {})
|
13
|
+
super(opts)
|
14
|
+
|
15
|
+
@region = opts[:region] || 'us'
|
16
|
+
@default_hosts = [Transport::StatefulHost.new("personalization.#{region}.algolia.com")]
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -1,20 +1,7 @@
|
|
1
1
|
module Algolia
|
2
2
|
module Recommendation
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
# Initialize a config
|
7
|
-
#
|
8
|
-
# @option options [String] :application_id
|
9
|
-
# @option options [String] :api_key
|
10
|
-
# @option options [String] :region
|
11
|
-
#
|
12
|
-
def initialize(opts = {})
|
13
|
-
super(opts)
|
14
|
-
|
15
|
-
@region = opts[:region] || 'us'
|
16
|
-
@default_hosts = [Transport::StatefulHost.new("recommendation.#{region}.algolia.com")]
|
17
|
-
end
|
3
|
+
# <b>DEPRECATED:</b> Please use <tt>Algolia::Personalization::Config</tt> instead.
|
4
|
+
class Config < Algolia::Personalization::Config
|
18
5
|
end
|
19
6
|
end
|
20
7
|
end
|
data/lib/algolia/helpers.rb
CHANGED
@@ -82,4 +82,53 @@ module Helpers
|
|
82
82
|
end
|
83
83
|
res
|
84
84
|
end
|
85
|
+
|
86
|
+
# Check the passed object to determine if it's an array
|
87
|
+
#
|
88
|
+
# @param object [Object]
|
89
|
+
#
|
90
|
+
def check_array(object)
|
91
|
+
raise Algolia::AlgoliaError, 'argument must be an array of objects' unless object.is_a?(Array)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Check the passed object
|
95
|
+
#
|
96
|
+
# @param object [Object]
|
97
|
+
# @param in_array [Boolean] whether the object is an array or not
|
98
|
+
#
|
99
|
+
def check_object(object, in_array = false)
|
100
|
+
case object
|
101
|
+
when Array
|
102
|
+
raise Algolia::AlgoliaError, in_array ? 'argument must be an array of objects' : 'argument must not be an array'
|
103
|
+
when String, Integer, Float, TrueClass, FalseClass, NilClass
|
104
|
+
raise Algolia::AlgoliaError, "argument must be an #{'array of' if in_array} object, got: #{object.inspect}"
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Check if passed object has a objectID
|
109
|
+
#
|
110
|
+
# @param object [Object]
|
111
|
+
# @param object_id [String]
|
112
|
+
#
|
113
|
+
def get_object_id(object, object_id = nil)
|
114
|
+
check_object(object)
|
115
|
+
object_id ||= object[:objectID] || object['objectID']
|
116
|
+
raise Algolia::AlgoliaError, "Missing 'objectID'" if object_id.nil?
|
117
|
+
object_id
|
118
|
+
end
|
119
|
+
|
120
|
+
# Build a batch request
|
121
|
+
#
|
122
|
+
# @param action [String] action to perform on the engine
|
123
|
+
# @param objects [Array] objects on which build the action
|
124
|
+
# @param with_object_id [Boolean] if set to true, check if each object has an objectID set
|
125
|
+
#
|
126
|
+
def chunk(action, objects, with_object_id = false)
|
127
|
+
objects.map do |object|
|
128
|
+
check_object(object, true)
|
129
|
+
request = { action: action, body: object }
|
130
|
+
request[:objectID] = get_object_id(object).to_s if with_object_id
|
131
|
+
request
|
132
|
+
end
|
133
|
+
end
|
85
134
|
end
|
@@ -9,9 +9,9 @@ module Algolia
|
|
9
9
|
# @param logger [Object] logger used to log requests. Defaults to Algolia::LoggerHelper
|
10
10
|
#
|
11
11
|
def initialize(adapter, logger)
|
12
|
-
@adapter
|
13
|
-
@logger
|
14
|
-
@
|
12
|
+
@adapter = adapter
|
13
|
+
@logger = logger
|
14
|
+
@connections = {}
|
15
15
|
end
|
16
16
|
|
17
17
|
# Sends request to the engine
|
@@ -65,7 +65,7 @@ module Algolia
|
|
65
65
|
# @return [Faraday::Connection]
|
66
66
|
#
|
67
67
|
def connection(host)
|
68
|
-
@
|
68
|
+
@connections[host.accept] ||= Faraday.new(build_url(host)) do |f|
|
69
69
|
f.adapter @adapter.to_sym
|
70
70
|
end
|
71
71
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
module Algolia
|
2
|
+
module Personalization
|
3
|
+
class Client
|
4
|
+
# Initializes the Personalization client
|
5
|
+
#
|
6
|
+
# @param personalization_config [Personalization::Config] a Personalization::Config object which contains your APP_ID and API_KEY
|
7
|
+
# @option adapter [Object] adapter object used for the connection
|
8
|
+
# @option logger [Object]
|
9
|
+
# @option http_requester [Object] http_requester object used for the connection
|
10
|
+
#
|
11
|
+
def initialize(personalization_config, opts = {})
|
12
|
+
@config = personalization_config
|
13
|
+
adapter = opts[:adapter] || Defaults::ADAPTER
|
14
|
+
logger = opts[:logger] || LoggerHelper.create('debug.log')
|
15
|
+
requester = opts[:http_requester] || Defaults::REQUESTER_CLASS.new(adapter, logger)
|
16
|
+
@transporter = Transport::Transport.new(@config, requester)
|
17
|
+
end
|
18
|
+
|
19
|
+
# Create a new client providing only app ID and API key
|
20
|
+
#
|
21
|
+
# @param app_id [String] Algolia application ID
|
22
|
+
# @param api_key [String] Algolia API key
|
23
|
+
#
|
24
|
+
# @return self
|
25
|
+
#
|
26
|
+
def self.create(app_id, api_key)
|
27
|
+
config = Personalization::Config.new(application_id: app_id, api_key: api_key)
|
28
|
+
create_with_config(config)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a new client providing only an Personalization::Config object
|
32
|
+
#
|
33
|
+
# @param config [Personalization::Config]
|
34
|
+
#
|
35
|
+
# @return self
|
36
|
+
#
|
37
|
+
def self.create_with_config(config)
|
38
|
+
new(config)
|
39
|
+
end
|
40
|
+
|
41
|
+
# Set the personalization strategy.
|
42
|
+
#
|
43
|
+
# @param personalization_strategy [Hash] A strategy object.
|
44
|
+
#
|
45
|
+
# @return [Hash]
|
46
|
+
#
|
47
|
+
def set_personalization_strategy(personalization_strategy, opts = {})
|
48
|
+
@transporter.write(:POST, '1/strategies/personalization', personalization_strategy, opts)
|
49
|
+
end
|
50
|
+
|
51
|
+
# Get the personalization strategy.
|
52
|
+
#
|
53
|
+
# @return [Hash]
|
54
|
+
#
|
55
|
+
def get_personalization_strategy(opts = {})
|
56
|
+
@transporter.read(:GET, '1/strategies/personalization', {}, opts)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -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
|
@@ -1,60 +1,7 @@
|
|
1
1
|
module Algolia
|
2
2
|
module Recommendation
|
3
|
-
|
4
|
-
|
5
|
-
#
|
6
|
-
# @param recommendation_config [Recommendation::Config] a Recommendation::Config object which contains your APP_ID and API_KEY
|
7
|
-
# @option adapter [Object] adapter object used for the connection
|
8
|
-
# @option logger [Object]
|
9
|
-
# @option http_requester [Object] http_requester object used for the connection
|
10
|
-
#
|
11
|
-
def initialize(recommendation_config, opts = {})
|
12
|
-
@config = recommendation_config
|
13
|
-
adapter = opts[:adapter] || Defaults::ADAPTER
|
14
|
-
logger = opts[:logger] || LoggerHelper.create('debug.log')
|
15
|
-
requester = opts[:http_requester] || Defaults::REQUESTER_CLASS.new(adapter, logger)
|
16
|
-
@transporter = Transport::Transport.new(@config, requester)
|
17
|
-
end
|
18
|
-
|
19
|
-
# Create a new client providing only app ID and API key
|
20
|
-
#
|
21
|
-
# @param app_id [String] Algolia application ID
|
22
|
-
# @param api_key [String] Algolia API key
|
23
|
-
#
|
24
|
-
# @return self
|
25
|
-
#
|
26
|
-
def self.create(app_id, api_key)
|
27
|
-
config = Recommendation::Config.new(application_id: app_id, api_key: api_key)
|
28
|
-
create_with_config(config)
|
29
|
-
end
|
30
|
-
|
31
|
-
# Create a new client providing only an Recommendation::Config object
|
32
|
-
#
|
33
|
-
# @param config [Recommendation::Config]
|
34
|
-
#
|
35
|
-
# @return self
|
36
|
-
#
|
37
|
-
def self.create_with_config(config)
|
38
|
-
new(config)
|
39
|
-
end
|
40
|
-
|
41
|
-
# Set the personalization strategy.
|
42
|
-
#
|
43
|
-
# @param personalization_strategy [Hash] A strategy object.
|
44
|
-
#
|
45
|
-
# @return [Hash]
|
46
|
-
#
|
47
|
-
def set_personalization_strategy(personalization_strategy, opts = {})
|
48
|
-
@transporter.write(:POST, '1/strategies/personalization', personalization_strategy, opts)
|
49
|
-
end
|
50
|
-
|
51
|
-
# Get the personalization strategy.
|
52
|
-
#
|
53
|
-
# @return [Hash]
|
54
|
-
#
|
55
|
-
def get_personalization_strategy(opts = {})
|
56
|
-
@transporter.read(:GET, '1/strategies/personalization', {}, opts)
|
57
|
-
end
|
3
|
+
# <b>DEPRECATED:</b> Please use <tt>Algolia::Personalization::Client</tt> instead.
|
4
|
+
class Client < Algolia::Personalization::Client
|
58
5
|
end
|
59
6
|
end
|
60
7
|
end
|