> ## Documentation Index
> Fetch the complete documentation index at: https://algolia.com/llms.txt
> Use this file to discover all available pages before exploring further.

# FilterState

> Provides interface for managing applied filters.

export const Records = () => <Tooltip tip="A record is a searchable object in an Algolia index. Each record consists of named attributes." cta="Algolia records" href="/doc/guides/sending-and-managing-data/prepare-your-data#algolia-records">
    records
  </Tooltip>;

## 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 the [filtering guide](/doc/guides/managing-results/refine-results/filtering).
`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](/doc/guides/managing-results/refine-results/filtering/in-depth/combining-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.

<Card title="Explore example code" icon="github" href="https://github.com/algolia/instantsearch-ios/tree/master/Examples/Showcase">
  Browse the FilterState example code on GitHub.
</Card>

## 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 Swift icon=code theme={"system"}
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 Swift icon=code theme={"system"}
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 Swift icon=code theme={"system"}
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 Swift icon=code theme={"system"}
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](/doc/guides/managing-results/refine-results/filtering/in-depth/combining-boolean-operators)
which can be used with [`Query`](/doc/api-reference/widgets/configure/ios).

```swift Swift icon=code theme={"system"}
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 Swift icon=code theme={"system"}
let filterState: FilterState = ...
let query: Query = ...

query.facetFilters = filterState.description
```
