Skip to content

Commit 728b56a

Browse files
committed
Advanced search
1 parent b345040 commit 728b56a

File tree

11 files changed

+97
-70
lines changed

11 files changed

+97
-70
lines changed

src/commonMain/kotlin/com/algolia/search/client/Index.kt

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import com.algolia.search.endpoint.*
55
import com.algolia.search.model.Attribute
66
import com.algolia.search.model.IndexName
77
import com.algolia.search.model.filter.Filter
8+
import com.algolia.search.model.filter.FilterGroup
89
import com.algolia.search.model.multipleindex.IndexQuery
910
import com.algolia.search.model.response.ResponseSearch
1011
import com.algolia.search.model.response.ResponseSearchRules
@@ -109,15 +110,14 @@ public data class Index internal constructor(
109110
return responses
110111
}
111112

112-
suspend fun searchHierarchical(
113+
suspend fun advancedSearch(
113114
query: Query = Query(),
114-
disjunctiveFacets: List<Attribute> = listOf(),
115-
filters: Set<Filter> = setOf(),
116-
hierarchicalAttributes: List<Attribute> = listOf(),
117-
hierarchicalFilters: List<Filter.Facet> = listOf(),
115+
filterGroups: Set<FilterGroup<*>> = setOf(),
118116
requestOptions: RequestOptions? = null
119117
): ResponseSearch {
120-
val (filtersOr, filtersAnd) = filters.partition { disjunctiveFacets.contains(it.attribute) }
118+
val filtersAnd = filterGroups.filterIsInstance<FilterGroup.And<*>>().flatten()
119+
val filtersOr = filterGroups.filterIsInstance<FilterGroup.Or<*>>().flatten()
120+
val disjunctiveFacets = filtersOr.map { it.attribute }.toSet()
121121
val filtersOrFacet = filtersOr.filterIsInstance<Filter.Facet>()
122122
val filtersOrTag = filtersOr.filterIsInstance<Filter.Tag>()
123123
val filtersOrNumeric = filtersOr.filterIsInstance<Filter.Numeric>()
@@ -136,15 +136,22 @@ public data class Index internal constructor(
136136
.setFacets(attribute)
137137
.optimize()
138138
}
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-
}
139+
val queriesForHierarchicalFacets = filterGroups.filterIsInstance<FilterGroup.And.Hierarchical>().flatMap {
140+
it.attributes
141+
.take(it.path.size + 1)
142+
.mapIndexed { index, attribute ->
143+
query
144+
.toIndexQuery()
145+
.filters(
146+
filtersAnd.combine(it.path.getOrNull(index - 1)).minus(it.path.last()),
147+
filtersOrFacet,
148+
filtersOrTag,
149+
filtersOrNumeric
150+
)
151+
.setFacets(attribute)
152+
.optimize()
153+
}
154+
}
148155
val queries = listOf(queryForResults) + queriesForDisjunctiveFacets + queriesForHierarchicalFacets
149156
val response = EndpointMultipleIndexImpl(transport).multipleQueries(queries, requestOptions = requestOptions)
150157

src/commonMain/kotlin/com/algolia/search/dsl/filtering/DSLFacetFilters.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.algolia.search.model.filter.FilterGroup
1111
*/
1212
@DSLParameters
1313
public class DSLFacetFilters(
14-
private val groups: MutableList<FilterGroup<Filter.Facet>> = mutableListOf()
14+
private val groups: MutableSet<FilterGroup<Filter.Facet>> = mutableSetOf()
1515
) {
1616

1717
/**
@@ -35,10 +35,10 @@ public class DSLFacetFilters(
3535
+FilterGroup.Or.Facet(DSLGroupFacet(block))
3636
}
3737

38-
public companion object : DSL<DSLFacetFilters, List<FilterGroup<Filter.Facet>>> {
38+
public companion object : DSL<DSLFacetFilters, Set<FilterGroup<Filter.Facet>>> {
3939

40-
override operator fun invoke(block: DSLFacetFilters.() -> Unit): List<FilterGroup<Filter.Facet>> {
41-
return DSLFacetFilters().apply(block).groups.toList()
40+
override operator fun invoke(block: DSLFacetFilters.() -> Unit): Set<FilterGroup<Filter.Facet>> {
41+
return DSLFacetFilters().apply(block).groups
4242
}
4343
}
4444
}

src/commonMain/kotlin/com/algolia/search/dsl/filtering/DSLFilters.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.algolia.search.model.filter.FilterGroup
1111
*/
1212
@DSLParameters
1313
public class DSLFilters(
14-
private val groups: MutableList<FilterGroup<*>> = mutableListOf()
14+
private val groups: MutableSet<FilterGroup<*>> = mutableSetOf()
1515
) {
1616

1717
/**
@@ -49,10 +49,10 @@ public class DSLFilters(
4949
+FilterGroup.Or.Tag(DSLGroupTag(block))
5050
}
5151

52-
public companion object : DSL<DSLFilters, List<FilterGroup<*>>> {
52+
public companion object : DSL<DSLFilters, Set<FilterGroup<*>>> {
5353

54-
override operator fun invoke(block: DSLFilters.() -> Unit): List<FilterGroup<*>> {
55-
return DSLFilters().apply(block).groups.toList()
54+
override operator fun invoke(block: DSLFilters.() -> Unit): Set<FilterGroup<*>> {
55+
return DSLFilters().apply(block).groups
5656
}
5757
}
5858
}

src/commonMain/kotlin/com/algolia/search/dsl/filtering/DSLNumericFilters.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.algolia.search.model.filter.FilterGroup
1111
*/
1212
@DSLParameters
1313
public class DSLNumericFilters(
14-
private val groups: MutableList<FilterGroup<Filter.Numeric>> = mutableListOf()
14+
private val groups: MutableSet<FilterGroup<Filter.Numeric>> = mutableSetOf()
1515
) {
1616

1717
/**
@@ -35,10 +35,10 @@ public class DSLNumericFilters(
3535
+FilterGroup.Or.Numeric(DSLGroupNumeric(block))
3636
}
3737

38-
public companion object : DSL<DSLNumericFilters, List<FilterGroup<Filter.Numeric>>> {
38+
public companion object : DSL<DSLNumericFilters, Set<FilterGroup<Filter.Numeric>>> {
3939

40-
override operator fun invoke(block: DSLNumericFilters.() -> Unit): List<FilterGroup<Filter.Numeric>> {
41-
return DSLNumericFilters().apply(block).groups.toList()
40+
override operator fun invoke(block: DSLNumericFilters.() -> Unit): Set<FilterGroup<Filter.Numeric>> {
41+
return DSLNumericFilters().apply(block).groups
4242
}
4343
}
4444
}

src/commonMain/kotlin/com/algolia/search/dsl/filtering/DSLTagFilters.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import com.algolia.search.model.filter.FilterGroup
1111
*/
1212
@DSLParameters
1313
public class DSLTagFilters(
14-
private val groups: MutableList<FilterGroup<Filter.Tag>> = mutableListOf()
14+
private val groups: MutableSet<FilterGroup<Filter.Tag>> = mutableSetOf()
1515
) {
1616

1717
/**
@@ -35,10 +35,10 @@ public class DSLTagFilters(
3535
+FilterGroup.Or.Tag(DSLGroupTag(block))
3636
}
3737

38-
public companion object : DSL<DSLTagFilters, List<FilterGroup<Filter.Tag>>> {
38+
public companion object : DSL<DSLTagFilters, Set<FilterGroup<Filter.Tag>>> {
3939

40-
override operator fun invoke(block: DSLTagFilters.() -> Unit): List<FilterGroup<Filter.Tag>> {
41-
return DSLTagFilters().apply(block).groups.toList()
40+
override operator fun invoke(block: DSLTagFilters.() -> Unit): Set<FilterGroup<Filter.Tag>> {
41+
return DSLTagFilters().apply(block).groups
4242
}
4343
}
4444
}

src/commonMain/kotlin/com/algolia/search/model/filter/FilterGroup.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.algolia.search.model.filter
22

3+
import com.algolia.search.model.Attribute
4+
35

46
/**
57
* Contains a [Set] of [Filter] that should be evaluated together.
@@ -62,6 +64,13 @@ public sealed class FilterGroup<T : Filter> : Set<T> {
6264

6365
constructor(vararg filters: Filter.Numeric, name: String? = null) : this(filters.toSet(), name)
6466
}
67+
68+
public data class Hierarchical(
69+
override val filters: Set<Filter.Facet>,
70+
val path: List<Filter.Facet>,
71+
val attributes: List<Attribute>,
72+
override val name: String? = null
73+
) : And<Filter.Facet>(filters, name)
6574
}
6675

6776
/**

src/commonMain/kotlin/com/algolia/search/model/filter/FilterGroupsConverter.kt

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ public sealed class FilterGroupsConverter<I, O> : (I) -> O {
1010
* Converts a [List] of [FilterGroup] to its SQL-like [String] representation.
1111
* Returns null if the list is empty.
1212
*/
13-
public object SQL : FilterGroupsConverter<List<FilterGroup<*>>, String?>() {
13+
public object SQL : FilterGroupsConverter<Set<FilterGroup<*>>, String?>() {
1414

15-
override fun invoke(groups: List<FilterGroup<*>>): String? {
15+
override fun invoke(groups: Set<FilterGroup<*>>): String? {
1616
return if (groups.isNotEmpty()) {
1717
groups.joinToString(separator = " AND ") { group ->
1818
val separator = when (group) {
@@ -27,9 +27,9 @@ public sealed class FilterGroupsConverter<I, O> : (I) -> O {
2727
/**
2828
* Same as [SQL], but removes quotes for readability purposes.
2929
*/
30-
public object Unquoted : FilterGroupsConverter<List<FilterGroup<*>>, String?>() {
30+
public object Unquoted : FilterGroupsConverter<Set<FilterGroup<*>>, String?>() {
3131

32-
override fun invoke(groups: List<FilterGroup<*>>): String? {
32+
override fun invoke(groups: Set<FilterGroup<*>>): String? {
3333
return SQL(groups)?.replace("\"", "")
3434
}
3535
}
@@ -38,12 +38,11 @@ public sealed class FilterGroupsConverter<I, O> : (I) -> O {
3838
/**
3939
* Converts a [List] of [FilterGroup] to its legacy representation.
4040
*/
41-
public sealed class Legacy<T : Filter> : FilterGroupsConverter<List<FilterGroup<T>>, List<List<String>>>() {
41+
public sealed class Legacy<T : Filter> : FilterGroupsConverter<Set<FilterGroup<T>>, List<List<String>>>() {
4242

43-
override fun invoke(groups: List<FilterGroup<T>>): List<List<String>> {
43+
override fun invoke(groups: Set<FilterGroup<T>>): List<List<String>> {
4444
val (andEntries, orEntries) = groups.partition { it is FilterGroup.And }
45-
val ands =
46-
andEntries.flatMap { group -> group.flatMap { FilterConverter.Legacy(it) } }.map { listOf(it) }
45+
val ands = andEntries.flatMap { group -> group.flatMap { FilterConverter.Legacy(it) } }.map { listOf(it) }
4746
val ors = orEntries.map { group -> group.flatMap { FilterConverter.Legacy(it) } }
4847

4948
return ands + ors

src/commonTest/kotlin/dsl/filtering/TestDSLFacetFilters.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class TestDSLFacetFilters {
2020
}
2121
}
2222

23-
dsl shouldEqual listOf(
23+
dsl shouldEqual setOf(
2424
FilterGroup.And.Facet(Filter.Facet(attributeA, 0), Filter.Facet(attributeA, 1))
2525
)
2626
}
@@ -37,7 +37,7 @@ internal class TestDSLFacetFilters {
3737
}
3838
}
3939

40-
dsl shouldEqual listOf(
40+
dsl shouldEqual setOf(
4141
FilterGroup.Or.Facet(Filter.Facet(attributeA, 0), Filter.Facet(attributeB, 1)),
4242
FilterGroup.Or.Facet(Filter.Facet(attributeA, 0))
4343
)
@@ -50,6 +50,6 @@ internal class TestDSLFacetFilters {
5050
or { }
5151
}
5252

53-
dsl shouldEqual listOf()
53+
dsl shouldEqual setOf()
5454
}
5555
}

src/commonTest/kotlin/dsl/filtering/TestDSLNumericFilters.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class TestDSLNumericFilters {
2020
}
2121
}
2222

23-
dsl shouldEqual listOf(
23+
dsl shouldEqual setOf(
2424
FilterGroup.And.Numeric(Filter.Numeric(attributeA, 0..2), Filter.Numeric(attributeA, 1..2))
2525
)
2626
}
@@ -37,7 +37,7 @@ internal class TestDSLNumericFilters {
3737
}
3838
}
3939

40-
dsl shouldEqual listOf(
40+
dsl shouldEqual setOf(
4141
FilterGroup.Or.Numeric(Filter.Numeric(attributeA, 0..2), Filter.Numeric(attributeB, 1..2)),
4242
FilterGroup.Or.Numeric(Filter.Numeric(attributeA, 0..2))
4343
)
@@ -50,6 +50,6 @@ internal class TestDSLNumericFilters {
5050
or { }
5151
}
5252

53-
dsl shouldEqual listOf()
53+
dsl shouldEqual setOf()
5454
}
5555
}

src/commonTest/kotlin/dsl/filtering/TestDSLTagFilters.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ internal class TestDSLTagFilters {
2020
}
2121
}
2222

23-
dsl shouldEqual listOf(
23+
dsl shouldEqual setOf(
2424
FilterGroup.And.Tag(Filter.Tag(attributeA.raw), Filter.Tag(attributeB.raw))
2525
)
2626
}
@@ -37,7 +37,7 @@ internal class TestDSLTagFilters {
3737
}
3838
}
3939

40-
dsl shouldEqual listOf(
40+
dsl shouldEqual setOf(
4141
FilterGroup.Or.Tag(Filter.Tag(attributeA.raw), Filter.Tag(attributeB.raw)),
4242
FilterGroup.Or.Tag(Filter.Tag(attributeA.raw))
4343
)
@@ -50,6 +50,6 @@ internal class TestDSLTagFilters {
5050
or { }
5151
}
5252

53-
dsl shouldEqual listOf()
53+
dsl shouldEqual setOf()
5454
}
5555
}

0 commit comments

Comments
 (0)