-
Notifications
You must be signed in to change notification settings - Fork 61
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
Introduce finitePagination setting: remove default fetch of 200 documents #707
Conversation
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.
LGTM! 🥗
Hello! Awesome for this PR 🚀
Maybe remind the more you ask the search engine to retrieve documents, the more you impact the search time. Indeed meilisearch is designed to retrieve the most relevant documents, but not all the relevant documents. The more you ask, the more the search engine has to process. There is no difference regarding the search time between retrieving 6 or 7 documents, but between 6 and 200 documents to every request, the impact can be huge.
The examples are clear 👌 Finally, is it expected the README is not updated here? If it is, maybe you should add context in the PR description, like "the README will be updated in this PR", especially because this PR will be merged into Thank you again for the PR! |
Also, in the PR name, I would highlight the introduction of the |
@curquiza I think I added all your suggestions. Can you confirm that the readme now appears in this PR? Also, about the |
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.
Good documentation and nice PR description 👌
Also pinging @gmourier only for your information (about pagination héhé)
bors merge |
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.
Hi @bidoubiwa I left some comments about the fix, let me know if you need something :)
PS: I know I messed up with the timing, but I think is still helpful :)
|
||
### Finite Pagination | ||
|
||
Finite pagination is used when you want to add a numbered pagination at the bottom of your hits (for example: `< << 1, 2, 3 > >>`). |
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.
Finite pagination is used when you want to add a numbered pagination at the bottom of your hits (for example: `< << 1, 2, 3 > >>`). | |
Finite pagination is used when you want to add a numbered pagination at the bottom of your hits (for example: `< << 1, 2, 3 >> >`). |
@@ -6,6 +6,15 @@ module.exports = { | |||
'jest-watch-typeahead/filename', | |||
'jest-watch-typeahead/testname', | |||
], | |||
collectCoverage: true, |
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.
Oh, I saw the coverage in the CI, you have good coverage in this project, congrats! 🎉 🌮
@@ -148,4 +148,57 @@ describe('Pagination browser test', () => { | |||
const hits = response.results[0].hits | |||
expect(hits.length).toBe(6) | |||
}) | |||
|
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 did not know where I could add this, but is there a way to remove the "load more" and automate the "load more" request just by scrolling down?
If yes, last year I saw this video about how to make your app look better in infinite paginations. They have a trick with making two requests at once and I found it really great (despite being an ember tutorial, the concept is much valid) - but only if there is a way to automate the load more.
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 is possible by tweaking and customizing the instantsearch.js
see here
page: number | ||
} | ||
|
||
export type PaginationParams = { |
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.
You don't need this type right?
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.
This one has all its parameters being optional, the other one none are optional. That way once I initialized PaginationContext
using the information inPaginationParams
I travel around with an object that has either a value provided by PaginartionParams or a default value
// Limit | ||
if ((!placeholderSearch && query === '') || paginationTotalHits === 0) { | ||
// Pagination | ||
const { pagination } = searchContext |
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 was thinking of a way to reduce the complexity of this function, it seems this accumulated a lot of work in the last additions (and I have a feeling this will keep happening in the future 😬).
Maybe there is a way to apply the builder design pattern here, to build the meiliSearchParams
object in a clear way (but in a functional way).
Another way could be create smaller functions which will handle the data as a immutable param and return a new param like with the new composition:
// meilisearchParams = {}
meilisearchParams = addAttributesToRetrieve(meilisearchParams)
// meilisearchParams is now {attributesToCrop: [...]}
meilisearchParams = addAttributesToHighlight(meilisearchParams)
// meilisearchParams is now {attributesToCrop: [...], attributesToHighlight: [...]}
You could notice that this function is doing a lot because we have comments separating the responsibilities of the function like pagination, Attributes To Retrieve, filters...
.
Another thing I would like to ask is in line 20:
const meiliSearchParams: Record<string, any> = {}
, shouldn't be const meiliSearchParams: MeiliSearchParams = {}
?
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.
btw, I didn't find a good reference about a builder pattern in FP but looking at it, I found some good videos about FP in general
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.
const meiliSearchParams: Record<string, any> = {}, shouldn't be const meiliSearchParams: MeiliSearchParams = {}?
The issue lies with InstantSearchParams
being read-only and MeiliSearchParams
being not read-only. It results for example in
meiliSearchParams.facetsDistribution = searchContext?.facets
throwing:
Type 'readonly string[] | undefined' is not assignable to type 'string[] | undefined'.
The type 'readonly string[]' is 'readonly' and cannot be assigned to the mutable type 'string[]'.t
But by saying Record<string, any>
it removes this conflict. At the end, I still return a MeiliSearchParams
so if I created the object incorrectly it will throw an error anyway.
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.
For the builder pattern I think the adapter pattern is best suited! See #726
727: Cleaning in tests r=bidoubiwa a=bidoubiwa Based on these comments the tests are made more readable and consistent: - new lines between concerns - No redundant `Test` in front of test name - Creation of default contexts where possible - remove duplicated tests - Group related <hr> - #707 (comment) - #707 (comment) - #707 (comment) - #707 (comment) - #707 (comment) - #707 (comment) Co-authored-by: Charlotte Vermandel <charlottevermandel@gmail.com> Co-authored-by: cvermand <33010418+bidoubiwa@users.noreply.github.com>
Fixes: #569
fixes: #521
Previously
By default instant-meilisearch used to fetch 200 documents on every search request. This was needed to ensure we can provide a finite pagination when the user used the
pagination
widget (with the 1, 2, 3, at the bottom of the screen).Issue
This impacted the speed of the search considerably. Indeed meilisearch is designed to retrieve the most relevant documents, but not all the relevant documents. The more you ask, the more the search engine has to process. There is no difference regarding the search time between retrieving 6 or 7 documents, but between 6 and 200 documents to every request, the impact can be huge.
It also impacted users using the
infiniteHits
widget as well while it is not necessary for them. TheinfiniteHits
settings does not need to showcase a start and an end to the pagination. It only has to enable theshow more
button whenever there are more hits after the current showcased ones.New behavior
This PR introduces a new parameter:
finitePagination
.finitePagination
has a default value offalse
, when set to false, each search requests a limit:(hitsPerPage + 1) * (page + 1)
instantsearch
and default to6
) is the number of results on each page, or added on the current page on eachshow more
click in case of infiniteHits. In the case if infiniteHits, we need to be able to know if there are more hits to come to enable or disable theshow more
button. Thus we add1
tohitsPerPage
so that if Meilisearch returnshitsPerPage + 1
documents we know it has more.1
if you clicked once onload more
. Because it starts at0
, we add+1
for the multiplication.The pagination will stop at
paginationTotalHits
(default 200).When settings
finitePagination
totrue
, one search request will ask for a limit ofpaginationTotalHits
as limit. Thus in the default case, one search request will return200
documents.This number can be changed with
paginationTotalHits
The following will make one request of
7
documents ashitsPerPage
is at 6 by default.You can change hitsPerPage.
The following will make one request of 60 documents