Aggregate Filters
Aggregate filters (also known as facets) are a common tool in e-commerce to help customers narrow down the list of products. Filters for brand, category, price or size are a standard experience customers expect.
What sets aggregate filters apart from regular filters is the result count next to each filter option. The count represents the number of results available if that filter option was applied. This also means that only filters are shown that are actually relevant to the current result-set.
Search.io allows can return counts only or combine it with the filter option. This guide will take you through a number of examples on how to use and implement aggregate filter for your site.
The exact syntax of the variables in these examples can be customised via the pipeline steps. Each example below will also contain the pipeline step that is assumed to exist. For more details on the pipeline steps, read the aggregate filter section in Result settings.

Aggregates

Aggregates scan over a result set to count values, group results, and compute min, max and average of numeric values. They then return this data with the query response. For example, an aggregate on a category might return the count 20 for "tv", which means the search result contains 20 items that match the category "tv".
With this example the following count-aggregate step must be defined in the query pipeline.
1
- id: count-aggregate
2
params:
3
fields:
4
bind: countAggregate
Copied!
Search query: "q":"t-shirt"
The following aggregates will be used in this example:
  1. 1.
    Count size (assuming size is a String Array field)
  2. 2.
    Count color (assuming color is a String field)
Description:
Everything is run using the global search query as the starting point, so in this example all counts include records which satisfy the global text query t-shirts. Note: the global text query can be empty, in which case all records are included.
To start, we construct a query to return a count of all the size options for the query t-shirts.
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"countAggregate": "size"
5
}
6
}
Copied!
1
"aggregates": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"S": 140,
6
"M": 125,
7
"L": 180
8
}
9
}
10
}
11
} x
Copied!

Adding a color aggregate

Now let's add color to the query to return a count of all the size and color options for the query t-shirts.
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"countAggregate": "size,color"
5
}
6
}
Copied!
1
"aggregates": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"S": 140,
6
"M": 125,
7
"L": 180
8
}
9
}
10
},
11
"count.color": {
12
"count": {
13
"counts": {
14
"red": 30,
15
"green": 110,
16
"blue": 90,
17
"yellow": 60,
18
}
19
}
20
}
21
}
Copied!

Aggregate Filters

An aggregate filter is a pair, consisting of an aggregate and a filter. Aggregate filters change the result set to reflect the filters that are specified with them. An aggregate filter turns an aggregate into a filterable facet.
With this example the following count-aggregate-filter step must be defined in the query pipeline.
1
- id: count-aggregate-filter
2
params:
3
fields:
4
bind: count
5
filters:
6
bind: countFilters
Copied!

Returning counts

To start lets construct a query to return an unfiltered count of all the colour and size options for the query t-shirts.
The number of filters passed to countFilters must match the number of fields in the count variable. In the example above count has two variables and as no filters are being passed to countFilter its value is set to "countFilters": ",", which separates the blank filters with a comma.
Also note that field values are case sensitive.
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"count": "size,color",
5
"countFilters": ",",
6
}
7
}
Copied!
1
"aggregate_filters": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"S": 140,
6
"M": 125,
7
"L": 180
8
}
9
}
10
},
11
"count.color": {
12
"count": {
13
"counts": {
14
"red": 30,
15
"green": 110,
16
"blue": 90,
17
"yellow": 60,
18
}
19
}
20
}
21
}
Copied!

Filtering by color

If a user selects the blue color filter, we want the result set to include products with q = "t-shirt" AND color = "blue".
We also want the response to show counts for:
  • Size where: q = "t-shirt" AND color = "blue"
  • Colour where: q = "t-shirt"
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"count": "size,color",
5
"countFilters": ",color = 'blue'"
6
}
7
}
Copied!
1
"aggregate_filters": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"S": 56,
6
"M": 28,
7
"L": 63
8
}
9
}
10
},
11
"count.color": {
12
"count": {
13
"counts": {
14
"red": 30,
15
"green": 110,
16
"blue": 90,
17
"yellow": 60,
18
}
19
}
20
}
21
}
Copied!
The results now show all t-shirts that are available in the color blue. The facets show the same options for color, but the sizes are now updated to only show sizes that are available in blue, along with the corresponding count.

Filtering by size

If a user now selects the "M" size filter, we want the result set to include products with q = "t-shirt" AND color = "blue" AND size ~ ["M"].
We also want the response to show counts for:
  • Size where: q = "t-shirt" AND color = "blue"
  • Colour where: q = "t-shirt" AND size ~ ["M"]
Note, the size field is an array. Therefore the filter expression will check whether the size array ([]) contains (~) the size "M"
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"count": "size,color",
5
"countFilters": "size ~ ['M'],color = 'blue'"
6
}
7
}
Copied!
1
"aggregate_filters": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"M": 28
6
}
7
}
8
},
9
"count.color": {
10
"count": {
11
"counts": {
12
"blue": 90
13
}
14
}
15
}
16
}
Copied!

Example response

The results now show all t-shirts that are available in a blue and size M. The facets show all colours available in size M and all sizes available in blue, along with the corresponding count.

Combining Aggregates and Aggregate Filters

There may be scenarios where you need the unfiltered aggregate count and the filtered aggregate count. For this we use both Aggregates and Aggregate Filters
With this example the following count-aggregate and count-aggregate-filter steps must be defined in the query pipeline.
1
- id: count-aggregate
2
params:
3
fields:
4
bind: countAggregate
5
- id: count-aggregate-filter
6
params:
7
fields:
8
bind: count
9
filters:
10
bind: countFilters
Copied!

Returning counts and filtered counts

Our query has 3 objectives:
  1. 1.
    For the result set to only include products with q = "t-shirt" AND color = "blue" AND size ~ ["M"].
  2. 2.
    To use the Aggregate Filter so the response shows the following filtered counts:
    • Size where: q = "t-shirt" AND color = "blue"
    • Colour where: q = "t-shirt" AND size ~ ["M"]
  3. 3.
    To use the Aggregate so the response shows the following unfiltered counts:
    • Size where: q = "t-shirt"
    • Colour where: q = "t-shirt"
Request
Response
1
{
2
"variables": {
3
"q": "t-shirt",
4
"countAggregate": "size,color",
5
"count": "size,color",
6
"countFilters": "size ~ ['M'],color = 'blue'"
7
}
8
}
Copied!
1
"aggregates": {
2
"count.size": {
3
"count": {
4
"counts": {
5
"S": 140,
6
"M": 125,
7
"L": 180
8
}
9
}
10
},
11
"count.color": {
12
"count": {
13
"counts": {
14
"red": 30,
15
"green": 110,
16
"blue": 90,
17
"yellow": 60,
18
}
19
}
20
}
21
}
22
"aggregate_filters": {
23
"count.size": {
24
"count": {
25
"counts": {
26
"M": 28
27
}
28
}
29
},
30
"count.color": {
31
"count": {
32
"counts": {
33
"blue": 90
34
}
35
}
36
}
37
}
Copied!