docs: improve search to show results for all filters (#9208)
* docs: improve search to show results for all filters * fix index ordering
This commit is contained in:
@@ -97,7 +97,7 @@ export const SearchHits = ({
|
||||
setNoResults,
|
||||
checkInternalPattern,
|
||||
}: SearchHitsProps) => {
|
||||
const { hits } = useHits<HitType>()
|
||||
const { items: hits } = useHits<HitType>()
|
||||
const { status } = useInstantSearch()
|
||||
const { setIsOpen } = useSearch()
|
||||
|
||||
|
||||
@@ -13,6 +13,9 @@ import { checkArraySameElms } from "../../utils"
|
||||
import {
|
||||
liteClient as algoliasearch,
|
||||
LiteClient as SearchClient,
|
||||
type SearchResponses,
|
||||
type SearchHits,
|
||||
SearchResponse,
|
||||
} from "algoliasearch/lite"
|
||||
import clsx from "clsx"
|
||||
import { CSSTransition, SwitchTransition } from "react-transition-group"
|
||||
@@ -78,11 +81,37 @@ export const SearchProvider = ({
|
||||
async search(searchParams) {
|
||||
const requests =
|
||||
"requests" in searchParams ? searchParams.requests : searchParams
|
||||
const noQueries = requests.every(
|
||||
// always send this request, which is the main request with no filters
|
||||
const mainRequest = requests[0]
|
||||
|
||||
// retrieve only requests that have filters
|
||||
// this is to ensure that we show no result if no filter is selected
|
||||
const requestsWithFilters = requests.filter((item) => {
|
||||
if (
|
||||
!item.params ||
|
||||
typeof item.params !== "object" ||
|
||||
!("tagFilters" in item.params)
|
||||
) {
|
||||
return false
|
||||
}
|
||||
|
||||
const tagFilters = item.params.tagFilters as string[]
|
||||
|
||||
// if no tag filters are specified, there's still one item,
|
||||
// which is an empty array
|
||||
return tagFilters.length >= 1 && tagFilters[0].length > 0
|
||||
})
|
||||
|
||||
// check whether a query is entered in the search box
|
||||
const noQueries = requestsWithFilters.every(
|
||||
(item) =>
|
||||
("facetQuery" in item && !item.facetQuery) ||
|
||||
("query" in item && !item.query)
|
||||
!item.facetQuery &&
|
||||
(!item.params ||
|
||||
typeof item.params !== "object" ||
|
||||
!("query" in item.params) ||
|
||||
!item.params.query)
|
||||
)
|
||||
|
||||
if (noQueries) {
|
||||
return Promise.resolve({
|
||||
results: requests.map(() => ({
|
||||
@@ -99,7 +128,73 @@ export const SearchProvider = ({
|
||||
})
|
||||
}
|
||||
|
||||
return algoliaClient.search(searchParams)
|
||||
// split requests per tags
|
||||
const newRequests: typeof requestsWithFilters = [mainRequest]
|
||||
for (const request of requestsWithFilters) {
|
||||
const params = request.params as Record<string, unknown>
|
||||
const tagFilters = (params.tagFilters as string[][])[0]
|
||||
|
||||
// if only one tag is selected, keep the request as-is
|
||||
if (tagFilters.length === 1) {
|
||||
newRequests.push(request)
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
// if multiple tags are selected, split the tags
|
||||
// to retrieve a small subset of results per each tag.
|
||||
newRequests.push(
|
||||
...tagFilters.map((tag) => ({
|
||||
...request,
|
||||
params: {
|
||||
...params,
|
||||
tagFilters: [tag],
|
||||
},
|
||||
hitsPerPage: 4,
|
||||
}))
|
||||
)
|
||||
}
|
||||
|
||||
return algoliaClient
|
||||
.search<SearchHits>(newRequests)
|
||||
.then((response) => {
|
||||
// combine results of the same index and return the results
|
||||
const resultsByIndex: {
|
||||
[indexName: string]: SearchResponse<SearchHits>
|
||||
} = {}
|
||||
// extract the response of the main request
|
||||
const mainResult = response.results[0]
|
||||
|
||||
response.results.forEach((result, indexNum) => {
|
||||
if (indexNum === 0) {
|
||||
// ignore the main request's result
|
||||
return
|
||||
}
|
||||
const resultIndex = "index" in result ? result.index : undefined
|
||||
const resultHits = "hits" in result ? result.hits : []
|
||||
|
||||
if (!resultIndex) {
|
||||
return
|
||||
}
|
||||
|
||||
resultsByIndex[resultIndex] = {
|
||||
...result,
|
||||
...(resultsByIndex[resultIndex] || {}),
|
||||
hits: [
|
||||
...(resultsByIndex[resultIndex]?.hits || []),
|
||||
...resultHits,
|
||||
],
|
||||
nbHits:
|
||||
(resultsByIndex[resultIndex]?.nbHits || 0) +
|
||||
resultHits.length,
|
||||
}
|
||||
})
|
||||
|
||||
return {
|
||||
// append the results with the main request's results
|
||||
results: [mainResult, ...Object.values(resultsByIndex)],
|
||||
} as SearchResponses<any>
|
||||
})
|
||||
},
|
||||
}
|
||||
}, [algolia.appId, algolia.apiKey])
|
||||
|
||||
Reference in New Issue
Block a user