Skip to content

Commit dd7cd75

Browse files
Merge #726
726: Object constructor for search parameters r=bidoubiwa a=bidoubiwa In an effort to make a more maintainable code the huge function creating the search parameters is replaced by a more modular object creator. It is made based on the adapter pattern see [refactoring guru](https://refactoring.guru/design-patterns/adapter/typescript/example). With a somewhat similar example in javascript [here](https://www.dottedsquirrel.com/adapter-pattern-javascript/) Co-authored-by: Charlotte Vermandel <[email protected]>
2 parents 3f41839 + 1343503 commit dd7cd75

File tree

1 file changed

+130
-107
lines changed

1 file changed

+130
-107
lines changed

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

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

9+
/**
10+
* Adapts instantsearch.js and instant-meilisearch options
11+
* to meilisearch search query parameters.
12+
*
13+
* @param {SearchContext} searchContext
14+
*
15+
* @returns {MeiliSearchParams}
16+
*/
17+
function MeiliParamsCreator(searchContext: SearchContext) {
18+
const meiliSearchParams: Record<string, any> = {}
19+
const {
20+
facets,
21+
attributesToSnippet,
22+
snippetEllipsisText,
23+
attributesToRetrieve,
24+
filters,
25+
numericFilters,
26+
facetFilters,
27+
attributesToHighlight,
28+
highlightPreTag,
29+
highlightPostTag,
30+
placeholderSearch,
31+
query,
32+
finitePagination,
33+
sort,
34+
pagination,
35+
} = searchContext
36+
37+
return {
38+
getParams() {
39+
return meiliSearchParams
40+
},
41+
addFacets() {
42+
if (facets?.length) {
43+
meiliSearchParams.facets = facets
44+
}
45+
},
46+
addAttributesToCrop() {
47+
if (attributesToSnippet) {
48+
meiliSearchParams.attributesToCrop = attributesToSnippet
49+
}
50+
},
51+
addCropMarker() {
52+
// Attributes To Crop marker
53+
if (snippetEllipsisText != null) {
54+
meiliSearchParams.cropMarker = snippetEllipsisText
55+
}
56+
},
57+
addAttributesToRetrieve() {
58+
if (attributesToRetrieve) {
59+
meiliSearchParams.attributesToRetrieve = attributesToRetrieve
60+
}
61+
},
62+
addFilters() {
63+
const filter = adaptFilters(filters, numericFilters, facetFilters)
64+
if (filter.length) {
65+
meiliSearchParams.filter = filter
66+
}
67+
},
68+
addAttributesToHighlight() {
69+
meiliSearchParams.attributesToHighlight = attributesToHighlight || ['*']
70+
},
71+
addPreTag() {
72+
if (highlightPreTag) {
73+
meiliSearchParams.highlightPreTag = highlightPreTag
74+
} else {
75+
meiliSearchParams.highlightPreTag = '__ais-highlight__'
76+
}
77+
},
78+
addPostTag() {
79+
if (highlightPostTag) {
80+
meiliSearchParams.highlightPostTag = highlightPostTag
81+
} else {
82+
meiliSearchParams.highlightPostTag = '__/ais-highlight__'
83+
}
84+
},
85+
addPagination() {
86+
// Limit based on pagination preferences
87+
if (
88+
(!placeholderSearch && query === '') ||
89+
pagination.paginationTotalHits === 0
90+
) {
91+
meiliSearchParams.limit = 0
92+
} else if (finitePagination) {
93+
meiliSearchParams.limit = pagination.paginationTotalHits
94+
} else {
95+
const limit = (pagination.page + 1) * pagination.hitsPerPage + 1
96+
// If the limit is bigger than the total hits accepted
97+
// force the limit to that amount
98+
if (limit > pagination.paginationTotalHits) {
99+
meiliSearchParams.limit = pagination.paginationTotalHits
100+
} else {
101+
meiliSearchParams.limit = limit
102+
}
103+
}
104+
},
105+
addSort() {
106+
if (sort?.length) {
107+
meiliSearchParams.sort = [sort]
108+
}
109+
},
110+
addGeoSearchRules() {
111+
const geoSearchContext = createGeoSearchContext(searchContext)
112+
const geoRules = adaptGeoPointsRules(geoSearchContext)
113+
114+
if (geoRules?.filter) {
115+
if (meiliSearchParams.filter) {
116+
meiliSearchParams.filter.unshift(geoRules.filter)
117+
} else {
118+
meiliSearchParams.filter = [geoRules.filter]
119+
}
120+
}
121+
},
122+
}
123+
}
124+
9125
/**
10126
* Adapt search request from instantsearch.js
11127
* to search request compliant with Meilisearch
@@ -16,111 +132,18 @@ import { adaptFilters } from './filter-adapter'
16132
export function adaptSearchParams(
17133
searchContext: SearchContext
18134
): MeiliSearchParams {
19-
// Creates search params object compliant with Meilisearch
20-
const meiliSearchParams: Record<string, any> = {}
21-
22-
// Facets
23-
const facets = searchContext?.facets
24-
if (facets?.length) {
25-
meiliSearchParams.facets = facets
26-
}
27-
28-
// Attributes To Crop
29-
const attributesToCrop = searchContext?.attributesToSnippet
30-
if (attributesToCrop) {
31-
meiliSearchParams.attributesToCrop = attributesToCrop
32-
}
33-
34-
// Attributes To Crop marker
35-
const cropMarker = searchContext?.snippetEllipsisText
36-
if (cropMarker != null) {
37-
meiliSearchParams.cropMarker = cropMarker
38-
}
39-
40-
// Attributes To Retrieve
41-
const attributesToRetrieve = searchContext?.attributesToRetrieve
42-
if (attributesToRetrieve) {
43-
meiliSearchParams.attributesToRetrieve = attributesToRetrieve
44-
}
45-
46-
// Filter
47-
const filter = adaptFilters(
48-
searchContext?.filters,
49-
searchContext?.numericFilters,
50-
searchContext?.facetFilters
51-
)
52-
if (filter.length) {
53-
meiliSearchParams.filter = filter
54-
}
55-
56-
// Attributes To Retrieve
57-
if (attributesToRetrieve) {
58-
meiliSearchParams.attributesToCrop = attributesToRetrieve
59-
}
60-
61-
// Attributes To Highlight
62-
meiliSearchParams.attributesToHighlight = searchContext?.attributesToHighlight || [
63-
'*',
64-
]
65-
66-
// Highlight pre tag
67-
const highlightPreTag = searchContext?.highlightPreTag
68-
if (highlightPreTag) {
69-
meiliSearchParams.highlightPreTag = highlightPreTag
70-
} else {
71-
meiliSearchParams.highlightPreTag = '__ais-highlight__'
72-
}
73-
74-
// Highlight post tag
75-
const highlightPostTag = searchContext?.highlightPostTag
76-
if (highlightPostTag) {
77-
meiliSearchParams.highlightPostTag = highlightPostTag
78-
} else {
79-
meiliSearchParams.highlightPostTag = '__/ais-highlight__'
80-
}
81-
82-
const placeholderSearch = searchContext.placeholderSearch
83-
const query = searchContext.query
84-
85-
// Pagination
86-
const { pagination } = searchContext
87-
88-
// Limit based on pagination preferences
89-
if (
90-
(!placeholderSearch && query === '') ||
91-
pagination.paginationTotalHits === 0
92-
) {
93-
meiliSearchParams.limit = 0
94-
} else if (searchContext.finitePagination) {
95-
meiliSearchParams.limit = pagination.paginationTotalHits
96-
} else {
97-
const limit = (pagination.page + 1) * pagination.hitsPerPage + 1
98-
// If the limit is bigger than the total hits accepted
99-
// force the limit to that amount
100-
if (limit > pagination.paginationTotalHits) {
101-
meiliSearchParams.limit = pagination.paginationTotalHits
102-
} else {
103-
meiliSearchParams.limit = limit
104-
}
105-
}
106-
107-
const sort = searchContext.sort
108-
109-
// Sort
110-
if (sort?.length) {
111-
meiliSearchParams.sort = [sort]
112-
}
113-
114-
const geoSearchContext = createGeoSearchContext(searchContext)
115-
const geoRules = adaptGeoPointsRules(geoSearchContext)
116-
117-
if (geoRules?.filter) {
118-
if (meiliSearchParams.filter) {
119-
meiliSearchParams.filter.unshift(geoRules.filter)
120-
} else {
121-
meiliSearchParams.filter = [geoRules.filter]
122-
}
123-
}
124-
125-
return meiliSearchParams
135+
const meilisearchParams = MeiliParamsCreator(searchContext)
136+
meilisearchParams.addFacets()
137+
meilisearchParams.addAttributesToHighlight()
138+
meilisearchParams.addPreTag()
139+
meilisearchParams.addPostTag()
140+
meilisearchParams.addAttributesToRetrieve()
141+
meilisearchParams.addAttributesToCrop()
142+
meilisearchParams.addCropMarker()
143+
meilisearchParams.addPagination()
144+
meilisearchParams.addFilters()
145+
meilisearchParams.addSort()
146+
meilisearchParams.addGeoSearchRules()
147+
148+
return meilisearchParams.getParams()
126149
}

0 commit comments

Comments
 (0)