Guide on pagination
bidoubiwa opened this issue · 4 comments
Pagination best practice
MeiliSearch was not made for pagination. The idea is that you never have to "go to page 2".
In case you still want pagination, let us consider two pagination styles.
1. Infinity scroll, or arrow pagination: recommended
This pagination is recognizable by its absence of a numbered paginated page. It will either have no visual clues and will be done in the background while you scroll down infinitely (i.e.: dev.to) or using arrows that let you navigate to the next page of results.
To achieve this pagination you should make searches based on two pieces of information.
- How much result do you want to have on a single page (or add on one scroll)
- Are there anymore hits after this batch?
Showing a certain amount of hits per batch can be done using the limit. But since you don't want to give the possibility to your user to click on the right arrow if there are no more hits, you need to know where to stop. We suggest to always add + 1
on your limit count, if the number of results MeiliSearch returns is lower than this number, you should inform the user that he arrived at the end the results (by graying out the arrow for example).
For this example, let's say that we want 100 hits per page. Pagination will work like this. We will be using two search parameter to achieve pagination: limit and offset
- Make a first search on
batman
with limit:101
and offset:0
.- As we receive
101
results we know that there are more results. - We show 100 hits
- We add a right arrow at the bottom
- As we receive
- The user scrolls to the end of the page or clicks on the right arrow
- Trigger another search on
batman
with limit:101
and offset:100
- As we receive
101
results we know that there are more results. - We show 100 hits
- We add a right arrow at the bottom
- As we receive
- The user scrolls to the end of the page or clicks on the right arrow
- Trigger another search on
batman
with limit:100
and offset:200
- As we receive only
10
results we know that there are NO more possible results. - We show 100 hits
- We grey out a right arrow at the bottom
- As we receive only
- The users can not click on the right arrow
As you may observe, the only parameter changing between each pagination is the offset.
1000
hits. Because the bigger the offset the longer it takes MeiliSearch to return the next results. This can be done by putting a limit on the offset value. This performance issue is due to the fact that MeiliSearch needs to sort limit + offset
documents before returning the results. Thus instead of stoping the sort at 20 documents, it would have to stop the sort at 220 documents. Which takes more time.
2. Numbered Pagination or Finished Pagination: NOT recommended
this is NOT recommended
Finished pagination is the most known pagination system:
While it has its uses, it is not a style that fits well with MeiliSearch.
No exact knowledge of the nb of hits
Meilisearch search response info nbHits
is most of the time an upper bound approximation of the numbers of hits. It is not a reliable information unless the other search response info exhaustiveNbHits
is true
.
Perfomances issues
Another problem comes from performance issues when paginating to lets say page 200. Since we are using a bucket sort, having the first 20 results is way faster than having the 2000th result.
So giving the possibility to a user to directly jump to page 200 is not a good experience.
Because of this behavior we do not recommend a finished pagination.
How to make a numbered pagination with limited damage
If you want to create finished pagination you need to set a limit of results during your search. MeiliSearch is designed to fastly retrieve the best matching documents (the 20 firsts in a basic search request) but not to return the exact and exhaustive number of documents matching your request, for performance reasons.
What you concretely have to do is to set the limit
search parameter to 1000
.
MeiliSearch will return a hits
array (less or equals to 1000) and the length of thishits
array is the number of results -> you can now know the number of pages.
Depending on which page you want to display, you just have to take the piece of hits
you need to display the expected results.
Example:
I have a front end application with finished pagination and I want to display 10 results per page.
I search for prince
with limit
set to 1000.
I get 32 results in hits
.
- I know that I have 22 / 10 = 2,2 => 3 pages to display
- I will display the hits from
0
to9
for page 1,10
to19
for page 2, and20
to22
for the last page.
💡As this technique lowers the performance of the search **we recommend setting the limit of results to a maximum of 1000 **. If you want to improve your performance, you can choose a lower limit. Algolia also sets the limit to 1000 for their pagination by default (see this page of docs).
Todo
Creation of a guide
A (small) guide should be made explaining how to create a pagination system with MeiliSearch.
This guide will be added in the search
main concept guide as an example of what can be done using the search route.
The guide should only use curl
and MeiliSearch routes. No other external library. Once it is written with cURL
our other clients (ruby, js, php,..) will be able to add code-samples to match the cURL
examples and thus the guide will be available in all languages.
To showcase the pagination, use both limit
and offset
but without using nbHits
as it is not a reliable source of information. It should explain to the user how to paginate with arrows :
For example, if every page should have 20 results, using the search routes it should look like this:
- Search on q = "batman", limit = 20, offset = 0
- Hit the arrow
- Search on q = "batman", limit = 20, offset = 20
- Hit the right arrow
- Search on q = "batman", limit = 20, offset = 40
...
The guide should mention the numbered pagination and explain that it is not recommended.
How to make a numbered pagination with limited damage
If you still want to create a numbered pagination system, we suggest you hard set the limit to
1000
results.
@curquiza could you confirm how to do this pagination system?
If you want to create a finished pagination you indeed need to set a limit of results during your search. MeiliSearch is designed to fastly retrieve the best matching documents (the 20 firsts in a basic search request) but not to return the exact and exhaustif number of documents matching your request, for performance reasons.
What you concretely have to do is to set the limit
search parameter to 1000
.
MeiliSearch will return a hits
array (less or equals to 1000) and the length of thishits
array is the number of results -> you can now know the number of pages.
Depending on which page you want to display, you just have to take the piece of hits
you need to display the expected results.
Example:
I have a front end application with a finished pagination and I want to display 10 results per page.
I search for prince
with limit
set to 1000.
I get 32 results in hits
.
- I know that I have 22 / 10 = 2,2 => 3 pages to display
- I will display the hits from
0
to9
for page 1,10
to19
for page 2, and20
to22
for the last page.
💡 Algolia sets the limit to 1000 for their pagination by default (see this page of docs), that's why we also recommend using 1000 as a limitation, but if you want to improve your performance, you can choose a lower limit.
@bidoubiwa and @gmourier created a rough draft(private link) of the pagination guide that @guimachiavelli will edit for release alongside v0.28 docs.
For those interested, the docs now have a dedicated guide explaining how to handle pagination in Meilisearch.
Hello!
For those interested, we are working on improving pagination in Meilisearch and we just released a first prototype that makes creating numbered pagination way easier! 🔥
It would be super helpful if you could let us know if this helps with your issue.
To know more about the prototype and how to use it, take a look at the dedicated discussion.