Skip to main content

About this widget

A FilterState consists of one or several filters, organized in groups. Each group can contain one or more of these filter types:
  • Facet.Filter
  • Facet.Numeric
  • Facet.Tag
You can read more about each filter type in our filtering guide. FilterState provides a simple interface to deal with filter grouping and their respective boolean operator. For more details, you can read more about filter grouping and boolean operators. Filter groups can be:
  • Conjunctive groups Search results will only contain hits that match all the filters in a conjunctive filter group. In other words, it represents a boolean and relationship between filters in this group. For example, if FilterState contains a conjunctive group of filters size:42 and category:shirt, records that match both filters will be returned. A conjunctive group may contain filters of any type at the same time.
  • Disjunctive groups Search results will contain hits that match any the filters in a disjunctive filter group. In other words, it represents a boolean or relationship between filters in this group. For example, if FilterState contains a disjunctive group of filters color:red and color:blue, records that match any of these filters will be returned. Disjunctive group may only contain filters of the same type. For example, you can’t put a facet filter and a tag filter in the same disjunctive group.
The set of groups in FilterState behave as if they’re combined by an AND operator. That means that a record matches the set of filters in FilterState only if it satisfies all the groups simultaneously.

Examples

To access filter groups, FilterState provides a subscript syntax. Each group is identified by its name (string). You can access groups by using [and: "groupName"] for conjunctive groups and [or: "groupName"] for disjunctive groups. Groups are automatically created when you add the first filter, and are deleted when they’re empty.
Swift
let filterState = FilterState()

// Add filter to conjunctive group
filterState[and: "conjunctiveGroup"].add(Filter.Facet(attribute: "category", stringValue: "shirts"))

// Add filter to disjunctive group
filterState[or: "disjunctiveGroup"].add(Filter.Facet(attribute: "color", stringValue: "red"))

print(filterState.debugDescription)

/* Output:
FilterState {
 "conjunctiveGroup": ( "category":"shirts" )
 "disjunctiveGroup": ( "color":"red" )
}
*/
Disjunctive groups with different type of filters are considered as different groups.
Swift
let filterState = FilterState()

filterState[or: "disjunctiveGroup"].add(Filter.Facet(attribute: "color", stringValue: "red"),
                                        Filter.Facet(attribute: "color", stringValue: "blue"))
filterState[or: "disjunctiveGroup"].add(Filter.Numeric(attribute: "price", range: 10...100))
filterState[or: "disjunctiveGroup"].add(Filter.Tag(stringLiteral: "sales"))

print(filterState.debugDescription)

// Three different groups have been created with the same name according to type
/* Output:
FilterState {
 "disjunctiveGroup": ( "_tags":"sales" )
 "disjunctiveGroup": ( "color":"blue" OR "color":"red" )
 "disjunctiveGroup": ( "price":10.0 TO 100.0 )
}
*/
Group accessors in FilterState provide convenient functionalities such as filter removal:
Swift
let filterState = FilterState()
let tagFilter = Filter.Tag(stringLiteral: "sales")

filterState[and: "conjunctiveGroup"].add(tagFilter)
print(filterState.debugDescription)

/* Output:
FilterState {
  "conjunctiveGroup": ( "_tags":"sales" )
}
*/

filterState[and: "conjunctiveGroup"].remove(tagFilter)
print(filterState.debugDescription)

/* Output:
FilterState {}
*/
and toggling:
Swift
let filterState = FilterState()
let tagFilter = Filter.Tag(stringLiteral: "sales")

filterState[and: "conjunctiveGroup"].toggle(tagFilter)
print(filterState.debugDescription)

/* Output:
FilterState {
  "conjunctiveGroup": ( "_tags":"sales" )
}
*/

filterState[and: "conjunctiveGroup"].toggle(tagFilter)
print(filterState.debugDescription)

/* Output:
FilterState {}
*/

Transform to SQL syntax string

InstantSearch provides a convenient way to transform a FilterState into a valid SQL-like string expression which can be used with Query.
Swift
let filterState: FilterState = ...

// convert FilterState to list of filter groups
let filterGroups = filterState.toFilterGroups()

// convert list of filter groups to Algolia filter SQL syntax
let filters = FilterGroupConverter().sql(filterGroups)

// set filters to Query
let query: Query = ...
query.facetFilters = filters

CustomStringConvertible conformity

FilterState conforms to the CustomStringConvertible protocol which provides the same valid SQL-like string with the description property. Therefore, the previous snippet can be reduced to this:
Swift
let filterState: FilterState = ...
let query: Query = ...

query.facetFilters = filterState.description
I