Skip to content
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

feat(ratingMenu): Add support for floats in values #4611

Merged
merged 12 commits into from
Jan 20, 2021
Merged

Conversation

yannickcr
Copy link
Contributor

Summary

This PR adds the support for floats to the ratingMenu connector.

Main changes

  • A new step option, so the user can control the step between ratings (example: 1 => 1, 2, 3, 4, 5 or 0.5 => 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5). Default to 1 so the original behavior is unchanged.
  • How the facetValues are calculated in the connector, taking this step option into account.
  • The widget now uses numericRefinements instead of disjunctiveFacetsRefinements since it is easier to specify a complete range of values (example: >=3) instead of being forced to specify all possible values manually (example: [3, 4, 5]) which can be very big if the range is large and/or if the steps are small (example: [3, 3.1, 3.2, 3.3, 3.4, etc.]). FMPOV it should not be a breaking change, but if this is the case we can still revert to disjunctiveFacetsRefinements (even if that's way less optimal IMHO).

Maximum facets values limitation

One big issue with the floats support is that the user is more likely to quickly hit the limit of retrievable facets values (limited to 1000 by the API).

For example imagine you have a rating from 0 to 10 with 2 decimals (example: 2.56, 3.78, 6.48, etc.). It means you have 10 integers and 100 values per integer = 1000 possible facets values. You reached the limit.

To avoid this issue as much as possible we need to guide the user so he can update his records and/or his configuration accordingly.

So if we detect that we enter this case where we did not retrieved enough facets the widget will display the following warning message:

[InstantSearch.js]: The price attribute can have 500000 different values (0 to 5000 with a maximum precision of 3 = 500000) but you retrieved only 10 facet values. Therefore the number of results that match the refinements can be incorrect.
To resolve this problem you can:
- Update your records to lower the precision of the values in the "price" attribute (for example: 5.12 to 5)
- Increase the maximum number of facet values to 1000 using the "configure" widget https://www.algolia.com/doc/api-reference/widgets/configure/js/ and the "maxValuesPerFacet" parameter https://www.algolia.com/doc/api-reference/api-parameters/maxValuesPerFacet/

This purpose of this message is to explain what is wrong in the current configuration, what are the consequences and to give some solutions to solve the problem.

Any ideas to improve this error message are welcome 😉

@codesandbox-ci
Copy link

codesandbox-ci bot commented Dec 22, 2020

This pull request is automatically built and testable in CodeSandbox.

To see build info of the built libraries, click here or the icon next to each commit SHA.

Latest deployment of this branch, based on commit d94781a:

Sandbox Source
InstantSearch.js Configuration

@@ -129,31 +132,77 @@ export default function connectRatingMenu(renderFn, unmountFn = noop) {
checkRendering(renderFn, withUsage());

return (widgetParams = {}) => {
const { attribute, max = 5 } = widgetParams;
const { attribute, max = 5, step = 1 } = widgetParams;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I compared https://codesandbox.io/s/instantsearchjs-forked-ttnb0 (previous) and https://codesandbox.io/s/instantsearchjs-forked-92pyp?file=/src/app.js (with this PR) and the number of results changed, even without changing the step. Should we have a default that allows only integer? I'm not sure what step means. If I set it to 1, the warning still shows up, and 2 I think it rounds oddly?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The new implementation was keeping the values >= to max into the count, while the previous implementation was ignoring them. I fixed the calculation to match the previous implementation.

The step parameter changes how the results get visually grouped, for example if you want to display half-stars you can set the step to 0.5.

Grouping with step set to 1 (default):

>= 4
>= 3
>= 2
>= 1

Grouping with step set to 0.5:

>= 4.5
>= 4
>= 3.5
>= 3
>= 2.5
>= 2
>= 1.5
>= 1
>= 0.5

Changing the grouping does not affect the warning, the only solutions I found to get the correct count (and therefore to fix the warning) is to lower the precision of the values (less possible facet values) and/or to retrieve more facets (to get all possible values).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've updated both sandboxes and the count is now more reasonable, but neither really work as expected (saying ~100 hits, while really there are thousands, in the previous implementation 1 hit).

Since the hits are so different, I think this is a breaking change (unfortunately)

Copy link
Contributor Author

@yannickcr yannickcr Jan 15, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the implementation to apply the maximum value in the refinement.

eg. you add a ratingMenu with a maximum value of 5 and apply a refinement on 3 and up, you'll get numericFilters: ["price<=5","price>=3"]. The count is accurate then.

You can still have some small imprecision on the count but I think this is due to engine limitations (to confirm).

Copy link
Contributor

@Haroenv Haroenv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is still a potential breaking change, but the behaviour in the new version is now much clearer and more correct:

new vs. old

@yannickcr
Copy link
Contributor Author

yannickcr commented Jan 18, 2021

@Haroenv

this is still a potential breaking change

This is the last main issue imho. As we saw together it is not possible to get the correct count if you reach the limit of possible facet values. With the previous implementation the count was obviously incorrect, now with this implementation the count is "more correct", even if not exact. Do we consider this change of behavior as a breaking change or not? For me it is closer to a fix than something else (since the previous behavior was incorrect), therefore if should not be considered as a breaking change.

(the above statement assume that the change from a disjunctiveFacetsRefinements to a numericRefinements is not a breaking change)

@yannickcr yannickcr requested a review from eunjae-lee January 18, 2021 16:55
@Haroenv
Copy link
Contributor

Haroenv commented Jan 19, 2021

I think for the moment, since the existing behaviour in this cases (floats) was very wrong, and it's better now, without significant impact on non-float ratings, we should put a note in the changelog, but it should be fine for the rest!

@eunjae-lee
Copy link
Contributor

Haven't checked this PR lately. Can you briefly explain to me (or, give me the line numbers) how it was broken and how it's fixed?
As you all mentioned, it shouldn't have to be a breaking change IMO. After all, seeing different facet count won't literally break anything.

@yannickcr
Copy link
Contributor Author

yannickcr commented Jan 19, 2021

@eunjae-lee

Before this change we were only handling integers in the rating menu.

In the previous implementation there was 2 main issues:

  1. We were grouping the values in the widget by rounding them ( https://github.com/algolia/instantsearch.js/pull/4611/files#diff-3ec5182253abc9786037ec058d37c2a07f7cc199ee639adfe4da638ca976bf4fL228 ) so an item with a rating of 3.9 was counted in the group "4 stars and up", which is incorrect.
  2. When sending the query we were filtering on the exact values, if you were asking for "3 stars and up" the facetFilter was ["rating:3","rating:4","rating:5"] so you were getting only the items with a round number of stars, excluding the items with a rating of 3.5 for example.

The first issue was fixed by not doing this rounding anymore (you can see how the new count is calculated here: https://github.com/algolia/instantsearch.js/pull/4611/files#diff-3ec5182253abc9786037ec058d37c2a07f7cc199ee639adfe4da638ca976bf4fR299-R302 ).

The second one by using a numericFilter instead of a facetFilter, so we ca use a range ["rating<=5","rating>=3"] and get all the possible values ( https://github.com/algolia/instantsearch.js/pull/4611/files#diff-3ec5182253abc9786037ec058d37c2a07f7cc199ee639adfe4da638ca976bf4fR200-R210 ).

Let me know is something is not clear and/or if the code could use some comments on a particular part 🙂

Copy link
Contributor

@eunjae-lee eunjae-lee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@yannickcr super clear. Thanks for the explanation.
The PR looks good to me.

@yannickcr yannickcr requested a review from Haroenv January 19, 2021 14:13
@yannickcr
Copy link
Contributor Author

@Haroenv I removed the step parameter, if that's good for you I think we are good to go 🙂

@yannickcr yannickcr merged commit 3f52784 into master Jan 20, 2021
@yannickcr yannickcr deleted the feat/rating-menu branch January 20, 2021 10:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants