Skip to content

Commit ca16eb2

Browse files
committed
Merge branch 'bump-meilisearch-v0.30.0' of https://github.com/meilisearch/instant-meilisearch into bump-meilisearch-v0.30.0-beta.0
2 parents bfa0300 + 31113ed commit ca16eb2

File tree

19 files changed

+544
-353
lines changed

19 files changed

+544
-353
lines changed

README.md

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -85,8 +85,7 @@ const searchClient = instantMeiliSearch(
8585
`instant-meilisearch` offers some options you can set to further fit your needs.
8686

8787
- [`placeholderSearch`](#placeholder-search): Enable or disable placeholder search (default: `true`).
88-
- [`paginationTotalHits`](#pagination-total-hits): Maximum total number of hits to create a finite pagination (default: `200`).
89-
- [`finitePagination`](#finite-pagination): Used to work with the [`pagination`](#-pagination) widget (default: `false`) .
88+
- [`finitePagination`](#finite-pagination): Enable finite pagination when using the the [`pagination`](#-pagination) widget (default: `false`) .
9089
- [`primaryKey`](#primary-key): Specify the primary key of your documents (default `undefined`).
9190
- [`keepZeroFacets`](#keep-zero-facets): Show the facets value even when they have 0 matches (default `false`).
9291
- [`matchingStrategy`](#matching-strategy): Determine the search strategy on words matching (default `last`).
@@ -100,7 +99,6 @@ const searchClient = instantMeiliSearch(
10099
'https://integration-demos.meilisearch.com',
101100
'99d1e034ed32eb569f9edc27962cccf90b736e4c5a70f7f5e76b9fab54d6a185',
102101
{
103-
paginationTotalHits: 30, // default: 200.
104102
placeholderSearch: false, // default: true.
105103
primaryKey: 'id', // default: undefined
106104
// ...
@@ -117,34 +115,18 @@ When placeholder search is set to `false`, no results appears when searching on
117115
{ placeholderSearch : true } // default true
118116
```
119117

120-
### Pagination total hits
121-
122-
The total (and finite) number of hits (default: `200`) you can browse during pagination when using the [pagination widget](https://www.algolia.com/doc/api-reference/widgets/pagination/js/) or the [`infiniteHits` widget](#-infinitehits). If none of these widgets are used, `paginationTotalHits` is ignored.<br>
123-
124-
For example, using the `infiniteHits` widget, and a `paginationTotalHits` of 9. On the first search request 6 hits are shown, by clicking a second time on `load more` only 3 more hits are added. This is because `paginationTotalHits` is `9`.
125-
126-
Usage:
127-
128-
```js
129-
{ paginationTotalHits: 50 } // default: 200
130-
```
131-
132-
`hitsPerPage` has a value of `20` by default and can [be customized](#-hitsperpage).
133-
134118
### Finite Pagination
135119

136120
Finite pagination is used when you want to add a numbered pagination at the bottom of your hits (for example: `<< < 1, 2, 3 > >>`).
137-
To be able to know the amount of page numbers you have, a search is done requesting `paginationTotalHits` documents (default: `200`).
138-
With the amount of documents returned, instantsearch is able to render the correct amount of numbers in the pagination widget.
121+
122+
It requires the usage of the [`Pagination` widget](#-pagination).
139123

140124
Example:
141125

142126
```js
143127
{ finitePagination: true } // default: false
144128
```
145129

146-
⚠️ Meilisearch is not designed for pagination and this can lead to performances issues, so the usage `finitePagination` but also of the pagination widgets are not recommended.<br>
147-
More information about Meilisearch and the pagination [here](https://github.com/meilisearch/documentation/issues/561).
148130

149131
### Primary key
150132

@@ -925,9 +907,7 @@ instantsearch.widgets.clearRefinements({
925907

926908
[Pagination references](https://www.algolia.com/doc/api-reference/widgets/pagination/js/)
927909

928-
The `pagination` widget displays a pagination system allowing the user to change the current page.
929-
930-
We do not recommend using this widget as pagination slows the search responses. Instead, the [InfiniteHits](#-infinitehits) component is recommended.
910+
The `pagination` widget displays a pagination system allowing the user to change the current page. It should be used alongside the [`finitePagination`](#finite-pagination) setting to render the correct amount of pages.
931911

932912
- ✅ container: The CSS Selector or HTMLElement to insert the widget into. _required_
933913
- ✅ showFirst: Whether to display the first-page link.
@@ -1094,4 +1074,4 @@ If you want to know more about the development workflow or want to contribute, p
10941074

10951075
<hr>
10961076

1097-
**Meilisearch** provides and maintains many **SDKs and Integration tools** like this one. We want to provide everyone with an **amazing search experience for any kind of project**. If you want to contribute, make suggestions, or just know what's going on right now, visit us in the [integration-guides](https://github.com/meilisearch/integration-guides) repository.
1077+
**Meilisearch** provides and maintains many **SDKs and Integration tools** like this one. We want to provide everyone with an **amazing search experience for any kind of project**. If you want to contribute, make suggestions, or just know what's going on right now, visit us in the [integration-guides](https://github.com/meilisearch/integration-guides) repository.

playgrounds/react/src/App.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ const searchClient = instantMeiliSearch(
2020
'https://integration-demos.meilisearch.com',
2121
'99d1e034ed32eb569f9edc27962cccf90b736e4c5a70f7f5e76b9fab54d6a185',
2222
{
23-
paginationTotalHits: 60,
2423
primaryKey: 'id',
2524
}
2625
)

src/adapter/search-request-adapter/__tests__/search-params.tests.ts

Lines changed: 21 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@ import { MatchingStrategies } from '../../../types'
33

44
const DEFAULT_CONTEXT = {
55
indexUid: 'test',
6-
pagination: { paginationTotalHits: 20, page: 0, hitsPerPage: 6 },
6+
pagination: { page: 0, hitsPerPage: 6, finite: false },
77
defaultFacetDistribution: {},
8-
finitePagination: false,
98
}
109

1110
describe('Parameters adapter', () => {
@@ -108,86 +107,63 @@ describe('Pagination adapter', () => {
108107
test('adapting a searchContext with finite pagination', () => {
109108
const searchParams = adaptSearchParams({
110109
...DEFAULT_CONTEXT,
111-
finitePagination: true,
110+
pagination: { page: 0, hitsPerPage: 6, finite: true },
112111
})
113112

114-
expect(searchParams.limit).toBe(20)
113+
expect(searchParams.page).toBe(1)
114+
expect(searchParams.hitsPerPage).toBe(6)
115115
})
116116

117117
test('adapting a searchContext with finite pagination on a later page', () => {
118118
const searchParams = adaptSearchParams({
119119
...DEFAULT_CONTEXT,
120-
pagination: { paginationTotalHits: 20, page: 10, hitsPerPage: 6 },
121-
finitePagination: true,
120+
pagination: { page: 10, hitsPerPage: 6, finite: true },
122121
})
123122

124-
expect(searchParams.limit).toBe(20)
123+
expect(searchParams.page).toBe(11)
124+
expect(searchParams.hitsPerPage).toBe(6)
125125
})
126126

127-
test('adapting a searchContext with finite pagination and pagination total hits lower than hitsPerPage', () => {
128-
const searchParams = adaptSearchParams({
129-
...DEFAULT_CONTEXT,
130-
pagination: { paginationTotalHits: 4, page: 0, hitsPerPage: 6 },
131-
finitePagination: true,
132-
})
133-
134-
expect(searchParams.limit).toBe(4)
135-
})
136-
137-
test('adapting a searchContext with no finite pagination', () => {
127+
test('adapting a searchContext with no finite pagination on page 1', () => {
138128
const searchParams = adaptSearchParams({
139129
...DEFAULT_CONTEXT,
140130
})
141131

142132
expect(searchParams.limit).toBe(7)
133+
expect(searchParams.offset).toBe(0)
143134
})
144135

145136
test('adapting a searchContext with no finite pagination on page 2', () => {
146137
const searchParams = adaptSearchParams({
147138
...DEFAULT_CONTEXT,
148-
pagination: { paginationTotalHits: 20, page: 1, hitsPerPage: 6 },
149-
})
150-
151-
expect(searchParams.limit).toBe(13)
152-
})
153-
154-
test('adapting a searchContext with no finite pagination on page higher than paginationTotalHits', () => {
155-
const searchParams = adaptSearchParams({
156-
...DEFAULT_CONTEXT,
157-
pagination: { paginationTotalHits: 20, page: 40, hitsPerPage: 6 },
139+
pagination: { page: 1, hitsPerPage: 6, finite: false },
158140
})
159141

160-
expect(searchParams.limit).toBe(20)
161-
})
162-
163-
test('adapting a searchContext with no finite pagination and pagination total hits lower than hitsPerPage', () => {
164-
const searchParams = adaptSearchParams({
165-
...DEFAULT_CONTEXT,
166-
pagination: { paginationTotalHits: 4, page: 0, hitsPerPage: 6 },
167-
})
168-
169-
expect(searchParams.limit).toBe(4)
142+
expect(searchParams.limit).toBe(7)
143+
expect(searchParams.offset).toBe(6)
170144
})
171145

172-
test('adapting a searchContext placeholderSearch set to false', () => {
146+
test('adapting a finite pagination with no placeholderSearch', () => {
173147
const searchParams = adaptSearchParams({
174148
...DEFAULT_CONTEXT,
175149
query: '',
176-
pagination: { paginationTotalHits: 4, page: 0, hitsPerPage: 6 },
150+
pagination: { page: 4, hitsPerPage: 6, finite: true },
177151
placeholderSearch: false,
178152
})
179153

180-
expect(searchParams.limit).toBe(0)
154+
expect(searchParams.page).toBe(5)
155+
expect(searchParams.hitsPerPage).toBe(0)
181156
})
182157

183-
test('adapting a searchContext placeholderSearch set to false', () => {
158+
test('adapting a scroll pagination with no placeholderSearch', () => {
184159
const searchParams = adaptSearchParams({
185160
...DEFAULT_CONTEXT,
186161
query: '',
187-
pagination: { paginationTotalHits: 200, page: 0, hitsPerPage: 6 },
188-
placeholderSearch: true,
162+
pagination: { page: 4, hitsPerPage: 6, finite: false },
163+
placeholderSearch: false,
189164
})
190165

191-
expect(searchParams.limit).toBe(7)
166+
expect(searchParams.limit).toBe(0)
167+
expect(searchParams.offset).toBe(0)
192168
})
193169
})

src/adapter/search-request-adapter/search-params-adapter.ts

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,43 @@ import {
66
} from './geo-rules-adapter'
77
import { adaptFilters } from './filter-adapter'
88

9+
function setScrollPagination(
10+
hitsPerPage: number,
11+
page: number,
12+
query?: string,
13+
placeholderSearch?: boolean
14+
): { limit: number; offset: number } {
15+
if (!placeholderSearch && query === '') {
16+
return {
17+
limit: 0,
18+
offset: 0,
19+
}
20+
}
21+
22+
return {
23+
limit: hitsPerPage + 1,
24+
offset: page * hitsPerPage,
25+
}
26+
}
27+
28+
function setFinitePagination(
29+
hitsPerPage: number,
30+
page: number,
31+
query?: string,
32+
placeholderSearch?: boolean
33+
): { hitsPerPage: number; page: number } {
34+
if (!placeholderSearch && query === '') {
35+
return {
36+
hitsPerPage: 0,
37+
page: page + 1,
38+
}
39+
} else {
40+
return {
41+
hitsPerPage: hitsPerPage,
42+
page: page + 1,
43+
}
44+
}
45+
}
946
/**
1047
* Adapts instantsearch.js and instant-meilisearch options
1148
* to meilisearch search query parameters.
@@ -29,7 +66,6 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
2966
highlightPostTag,
3067
placeholderSearch,
3168
query,
32-
finitePagination,
3369
sort,
3470
pagination,
3571
matchingStrategy,
@@ -84,23 +120,24 @@ export function MeiliParamsCreator(searchContext: SearchContext) {
84120
}
85121
},
86122
addPagination() {
87-
// Limit based on pagination preferences
88-
if (
89-
(!placeholderSearch && query === '') ||
90-
pagination.paginationTotalHits === 0
91-
) {
92-
meiliSearchParams.limit = 0
93-
} else if (finitePagination) {
94-
meiliSearchParams.limit = pagination.paginationTotalHits
123+
if (pagination.finite) {
124+
const { hitsPerPage, page } = setFinitePagination(
125+
pagination.hitsPerPage,
126+
pagination.page,
127+
query,
128+
placeholderSearch
129+
)
130+
meiliSearchParams.hitsPerPage = hitsPerPage
131+
meiliSearchParams.page = page
95132
} else {
96-
const limit = (pagination.page + 1) * pagination.hitsPerPage + 1
97-
// If the limit is bigger than the total hits accepted
98-
// force the limit to that amount
99-
if (limit > pagination.paginationTotalHits) {
100-
meiliSearchParams.limit = pagination.paginationTotalHits
101-
} else {
102-
meiliSearchParams.limit = limit
103-
}
133+
const { limit, offset } = setScrollPagination(
134+
pagination.hitsPerPage,
135+
pagination.page,
136+
query,
137+
placeholderSearch
138+
)
139+
meiliSearchParams.limit = limit
140+
meiliSearchParams.offset = offset
104141
}
105142
},
106143
addSort() {

src/adapter/search-request-adapter/search-resolver.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -27,27 +27,19 @@ export function SearchResolver(
2727
): Promise<MeiliSearchResponse<Record<string, any>>> {
2828
const { placeholderSearch, query } = searchContext
2929

30-
const { pagination } = searchContext
31-
32-
// In case we are in a `finitePagination`, only one big request is made
33-
// containing a total of max the paginationTotalHits (default: 200).
34-
// Thus we dont want the pagination to impact the cache as every
35-
// hits are already cached.
36-
const paginationCache = searchContext.finitePagination ? {} : pagination
37-
3830
// Create cache key containing a unique set of search parameters
3931
const key = cache.formatKey([
4032
searchParams,
4133
searchContext.indexUid,
4234
searchContext.query,
43-
paginationCache,
35+
searchContext.pagination,
4436
])
4537
const cachedResponse = cache.getEntry(key)
4638

4739
// Check if specific request is already cached with its associated search response.
4840
if (cachedResponse) return cachedResponse
4941

50-
const facetsCache = extractFacets(searchContext, searchParams)
42+
const cachedFacets = extractFacets(searchContext, searchParams)
5143

5244
// Make search request
5345
const searchResponse = await client
@@ -56,7 +48,7 @@ export function SearchResolver(
5648

5749
// Add missing facets back into facetDistribution
5850
searchResponse.facetDistribution = addMissingFacets(
59-
facetsCache,
51+
cachedFacets,
6052
searchResponse.facetDistribution
6153
)
6254

0 commit comments

Comments
 (0)