-
Notifications
You must be signed in to change notification settings - Fork 7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
User recommendation command #31
Conversation
Also the filters could be defined as an array of strings, and concatenated to output string only on build(). This will allow simpler manipulation with the default filter, adding custom filters atd. Or could the default filter be defined as standalone property - what would allow to simply overwrite it eg. through RequestManager. |
*/ | ||
public function setMinimalRelevance(string $minimalRelevance): self | ||
{ | ||
// TODO: assert one of MIN_RELEVANCE_* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe 3 setter should be provided e.g. setLowMinimalRelevance
etc. and no validation will be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe... If you find this interesting, we may add it later (or send a PR :) ), it would be quite easy to implement. However we are a bit on time pressure for MVP :).
/** @var string */ | ||
private $minimalRelevance = self::MINIMAL_RELEVANCE_LOW; | ||
/** @var string */ | ||
private $filter = 'valid_to >= NOW'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn`t this client specific?
valid_to
must be present in item properties.
Or I am wrong?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, its client specific.
Another argument is that 'filters' are client specific too (afaik all of them are still hardcoded).
So I suggests no default filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it is client specific, but:
- all but one client ;-) will use it as for now, so we can make life easier for the vast majority by defining the default filter like this;
- the one who does not use this default filter (but custome one), will anyway have to define the filter - so there will be no difference for him (define custom filter vs. overwrite default filter will be the same amount of work).
From the beginning we planned to have a simple way how to overwrite the default filter for all recommendations and sorting - so there will be no extra work for those not using the default filter. But for those who do use the default we will make the library adoption simpler, IMO.
Also, quoting Matej official docs:
Matej supports following filter:
valid_to >= NOW
which should be used in each recommendation request.
I will talk about this issue with RAD team and we may change this behavior in the future, however, having this feature in the API client was partially their idea ¯\_(ツ)_/¯.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There will be extra work for those who do not use default filter at all. They have to reset it. Or they end up with invalid request i guess.
It still seem weird to me to have default filter in such general library.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, they will not have to explicitly reset it. They will have to set custom filter anyway (and this will override the default one - if any). So no extra work for them. Because AFAIK there is no meaningful usecase for requesting recommendations without some kind of similar default filter.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. It might be useful though to have a way how to set the default filter for the customers use-case.
How about having a static variable that'll be the default value?
UserRecommendation::$DEFAULTS['filter'] = null;
How do other libs solve this?
Maybe smart default should also have
I think filters as an array would be better.
I don`t think we could find default filter that fits all clients. See my comment in review. |
@jirinovak And what would you suggest as default value for rotation rate and rotation time? The main criteria whether this should be required in constructor or customisable via setter is the the ratio of "creating request with the default values" vs "creating request with custom values". If you - for example - use in 90 % of cases the defaults, lets do it via setters. But if the ratio is 50:50 or so, maybe the cunstructor params is a better and more transparent way. |
As I said maybe the RAD team could provide |
So cc @foglcz - any suggestions :)? |
7c22d8c
to
a2f2edc
Compare
Ok, so:
Basic usage with default values$response = $matej->request()
->recommendation(UserRecommendation::create('user-id', 10, 'scenario'))
->send(); => this will use the default values:
Advanced usage with custom values$recommendationCommand = UserRecommendation::create('user-id', 10, 'scenario');
$recommendationCommand->setRotationRate(0.1337)
->setRotationTime(666)
->setMinimalRelevance(UserRecommendation::MINIMAL_RELEVANCE_HIGH)
->enableHardRotation()
->setFilters(['foo = bar', 'AND baz = ban']);
$response = $matej->request()
->recommendation($recommendationCommand)
->send(); |
I'm missing 'allowNonexistent' parameter - not part of this pull request? |
And with current "smart defaults" is client able to omit some parameters (e.g. rotationRate/rotationTime etc) with $command->setRotationTime(null)? It's sometimes useful for some A/B tests on Matej side. |
Got up to date feedback from RAD
|
For filters, I'd personally refrain from using Can we keep the array, but do a So that dev can use: $recommendationCommand = UserRecommendation::create('user-id', 10, 'scenario')
->setFilters(['foo = bar', 'baz = ban'])
->addFilter('bar = none')
; |
@tenerd Also - all parameters are required in the API request according to JSON schema. And eg. the value of rotation rate must be like this: |
Ok, I updated the PR - rotationRate and rotationTime are now required in the constructor, without any default value. Also the filters are now concatenated using filterOperator. However I kept this as protected, so one can eg. do custom implementation, what about that? |
} | ||
|
||
/** | ||
* Even with rotation rate 1.0 user could still obtain the same recommendations in some * edge cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The asterisk between the some
and edge
words has any reason?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, it has! It serves as an example of copy paste error 🙃 .
I will fix this, thanks for noticing.
* To prevent this, enable hard rotation - recommended items are then excluded until rotation time is expired. | ||
* By default hard rotation is not enabled. | ||
*/ | ||
public function enableHardRotation(): self |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not setHardRotation(bool $hardRotation)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It thought this is easier to read, don't you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, but you can't change the value back to false
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why would you need this?
And even if someone would need this, we can rather do disableHardRotation()
...
52f486f
a39c797
to
c49b243
Compare
c49b243
to
bd7a0fb
Compare
Not yet finished (+ with broken tests right now). However I'd like some feedback for the public API of the command.=> see comments for resolution
Outdated issue description:
The most basic case would look like this:
But still the constructor has so many required params... Maybe at least the hard rotation could be optional (and default to false?). The other values must be explicitly defined and there is no "smart default", if I'm not mistaken, right?
And when you will need more customized recommendation, you will have to call setters on the UserRecommendation object:
What do you think?