@@ -5,6 +5,7 @@ import com.algolia.search.endpoint.*
55import com.algolia.search.model.Attribute
66import com.algolia.search.model.IndexName
77import com.algolia.search.model.filter.Filter
8+ import com.algolia.search.model.filter.FilterGroup
89import com.algolia.search.model.multipleindex.IndexQuery
910import com.algolia.search.model.response.ResponseSearch
1011import com.algolia.search.model.response.ResponseSearchRules
@@ -108,113 +109,4 @@ public data class Index internal constructor(
108109 }
109110 return responses
110111 }
111-
112- suspend fun searchHierarchical (
113- query : Query = Query (),
114- disjunctiveFacets : List <Attribute > = listOf(),
115- filters : Set <Filter > = setOf(),
116- hierarchicalAttributes : List <Attribute > = listOf(),
117- hierarchicalFilters : List <Filter .Facet > = listOf(),
118- requestOptions : RequestOptions ? = null
119- ): ResponseSearch {
120- val (filtersOr, filtersAnd) = filters.partition { disjunctiveFacets.contains(it.attribute) }
121- val filtersOrFacet = filtersOr.filterIsInstance<Filter .Facet >()
122- val filtersOrTag = filtersOr.filterIsInstance<Filter .Tag >()
123- val filtersOrNumeric = filtersOr.filterIsInstance<Filter .Numeric >()
124- val queryForResults = query
125- .toIndexQuery()
126- .filters(filtersAnd, filtersOrFacet, filtersOrTag, filtersOrNumeric)
127- val queriesForDisjunctiveFacets = disjunctiveFacets.map { attribute ->
128- query
129- .toIndexQuery()
130- .filters(
131- filtersAnd,
132- filtersOrFacet.filter { it.attribute != attribute },
133- filtersOrTag,
134- filtersOrNumeric
135- )
136- .setFacets(attribute)
137- .optimize()
138- }
139- val queriesForHierarchicalFacets = hierarchicalAttributes
140- .take(hierarchicalFilters.size + 1 )
141- .mapIndexed { index, attribute ->
142- query
143- .toIndexQuery()
144- .filters(filtersAnd.combine(hierarchicalFilters.getOrNull(index - 1 )).minus(hierarchicalFilters.last()), filtersOrFacet, filtersOrTag, filtersOrNumeric)
145- .setFacets(attribute)
146- .optimize()
147- }
148- val queries = listOf (queryForResults) + queriesForDisjunctiveFacets + queriesForHierarchicalFacets
149- val response = EndpointMultipleIndexImpl (transport).multipleQueries(queries, requestOptions = requestOptions)
150-
151- return response.aggregateResult(disjunctiveFacets.size)
152- }
153-
154- private fun List<ResponseSearch>.aggregateFacets (): Map <Attribute , List <Facet >> {
155- return fold(mapOf ()) { acc, result ->
156- result.facetsOrNull?.let { acc + it } ? : acc
157- }
158- }
159-
160- private fun List<ResponseSearch>.aggregateFacetStats (): Map <Attribute , FacetStats > {
161- return fold(mapOf ()) { acc, result ->
162- result.facetStatsOrNull?.let { acc + it } ? : acc
163- }
164- }
165-
166- private fun List<Filter>.combine (hierarchicalFilter : Filter .Facet ? ): List <Filter > {
167- return hierarchicalFilter?.let { this + it } ? : this
168- }
169-
170- private fun ResponseSearches.aggregateResult (disjunctiveFacetCount : Int ): ResponseSearch {
171- val resultsDisjunctiveFacets = results.subList(1 , 1 + disjunctiveFacetCount)
172- val resultHierarchicalFacets = results.subList(1 + disjunctiveFacetCount, results.size)
173- val facets = resultsDisjunctiveFacets.aggregateFacets()
174- val facetStats = results.aggregateFacetStats()
175- val hierarchicalFacets = resultHierarchicalFacets.aggregateFacets()
176-
177- return results.first().copy(
178- facetStatsOrNull = if (facetStats.isEmpty()) null else facetStats,
179- disjunctiveFacetsOrNull = facets,
180- hierarchicalFacetsOrNull = if (hierarchicalFacets.isEmpty()) null else hierarchicalFacets,
181- exhaustiveFacetsCountOrNull = resultsDisjunctiveFacets.all { it.exhaustiveFacetsCountOrNull == true }
182- )
183- }
184-
185- private fun IndexQuery.optimize (): IndexQuery {
186- query.apply {
187- attributesToRetrieve = listOf ()
188- attributesToHighlight = listOf ()
189- hitsPerPage = 0
190- analytics = false
191- }
192- return this
193- }
194-
195- private fun Query.toIndexQuery (): IndexQuery {
196- return IndexQuery (indexName, copy())
197- }
198-
199- private fun IndexQuery.filters (
200- filtersAnd : List <Filter >,
201- filtersOrFacet : List <Filter .Facet >,
202- filtersOrTag : List <Filter .Tag >,
203- filtersOrNumeric : List <Filter .Numeric >
204- ): IndexQuery {
205- query.apply {
206- filters {
207- and { + filtersAnd }
208- orFacet { + filtersOrFacet }
209- orTag { + filtersOrTag }
210- orNumeric { + filtersOrNumeric }
211- }
212- }
213- return this
214- }
215-
216- private fun IndexQuery.setFacets (facet : Attribute ? ): IndexQuery {
217- if (facet != null ) query.facets = setOf (facet)
218- return this
219- }
220112}
0 commit comments