Algolia lets you filter on various types of attributes, including strings. For example, imagine you have an e-commerce website that sells smartphones, and you want to filter search results on a specific brand. With filters, you could allow users to refine results by selecting one or several brands or even exclude a specific brand.
Dataset Example
Let’s say we have an index called products
that looks like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
| [
{
"name": "iPhone XR Black 64GB",
"description": "iPhone XR features the most advanced LCD in a smartphone—a 6.1-inch Liquid Retina display with industry-leading color accuracy and an innovative backlight design that allows the screen to stretch into the corners.",
"brand": "Apple",
"price": 749.99
},
{
"name": "iPhone XS Gold 64GB",
"description": "The iPhone XS smartphone features a 5.8-inch Super Retina display with custom-built OLED panels for an HDR display that provides the industry’s best color accuracy, true blacks, and remarkable brightness.",
"brand": "Apple",
"price": 999.99
},
{
"name": "Galaxy Note9 Ocean Blue 128GB",
"description": "The new super powerful Note. Galaxy Note9 has the largest amount of storage offered in a Samsung smartphone.",
"brand": "Samsung",
"price": 900.00
},
{
"name": "G7 ThinQ™ Platinum Gray 64GB",
"description": "LG’S greatest smartphpne yet. Advanced AI multimedia phone!",
"brand": "LG",
"price": 600.00
},
{
"name": "Moto E5 Play 16GB",
"description": "Keep your smartphone protected with a water-repellent coating. Make room for more photos, songs, and videos with expandable storage.",
"brand": "Motorola",
"price": 150.00
},
...
]
|
With the above data structure, we can filter on the brand
attribute in a variety of ways:
- We could only show “Motorola” smartphones
- We could only show “LG” or “Samsung” smartphones
- We could show everything but “Apple” smartphones
However, before we can do that, we first need to set brand
as attributes for faceting.
Configuring attributesForFaceting
Using the API
First, you need to set brand
as attributesForFaceting
. This happens at indexing time.
Note that if you only need the filtering feature, you can take advantage of the filterOnly
modifier, which reduces the index size and improves the speed of the search.
1
2
3
4
5
| $index->setSettings([
'attributesForFaceting' => [
"brand" // or "filterOnly(brand)" for filtering purposes only
]
]);
|
1
2
3
4
5
| index.set_settings({
attributesForFaceting: [
'brand' # or 'filterOnly(brand)' for filtering purposes only
]
})
|
1
2
3
4
5
6
7
| index.setSettings({
attributesForFaceting: [
'brand' // or 'filterOnly(brand)' for filtering purposes only
]
}).then(() => {
// done
});
|
1
2
3
4
5
| index.set_settings({
'attributesForFaceting': [
'brand' # or 'filterOnly(brand)' for filtering purposes only
]
})
|
1
2
3
4
5
| index.setSettings([
"attributesForFaceting": [
"brand" // or "filterOnly(brand)" for filtering purposes only
]
])
|
1
2
3
4
5
6
7
| final JSONObject res = index.setSettings(
new JSONObject().put(
"attributesForFaceting",
new JSONArray()
.put("brand") // or "filterOnly(brand)" for filtering purposes only
)
);
|
1
2
3
4
5
6
7
8
9
10
11
12
| IndexSettings settings = new IndexSettings
{
AttributesForFaceting = new List<string>
{
"brand" // or "filterOnly(brand)" for filtering purposes only
}
};
replicaIndex.SetSettings(settings);
// Asynchronous
await replicaIndex.SetSettingsAsync(settings);
|
1
2
3
4
5
| index.setSettings(
new IndexSettings().setAttributesForFaceting(Collections.singletonList(
"brand" // or "filterOnly(brand)" for filtering purposes only
))
);
|
1
2
3
4
5
| res, err := index.SetSettings(search.Settings{
AttributesForFaceting: opt.AttributesForFaceting(
"brand", // or "filterOnly(brand)" for filtering purposes only
),
})
|
1
2
3
4
5
6
7
| client.execute {
changeSettings of "myIndex" `with` IndexSettings(
attributesForFaceting = Some(Seq(
"brand" // or "filterOnly(brand)" for filtering purposes only
))
)
}
|
1
2
3
4
5
6
7
| val settings = settings {
attributesForFaceting {
+"brand" // or FilterOnly(brand) for filtering purposes only
}
}
index.setSettings(settings)
|
Using the dashboard
You can set your attribute for faceting in your Algolia dashboard.
- Go to your dashboard and select your index.
- Click the Configuration tab.
- In the Facets subsection of Filtering and Faceting, click the “Add an attribute” button and select the
brand
attribute from the dropdown.
- Don’t forget to save your changes!
Applying a string filter
Using the API
Now, you can apply your filters. Note that you can only filter results at query time, not at indexing time. For this, you need to use the filters
parameter in your search
code.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Only “Motorola” smartphones
$results = $index->search('smartphone', [
'filters' => 'brand:Motorola'
]);
// Only “LG” or “Samsung” smartphones
$results2 = $index->search('smartphone', [
'filters' => 'brand:LG OR brand:Samsung'
]);
// Everything but “Apple” smartphones
$results3 = $index->search('smartphone', [
'filters' => 'NOT brand:Apple'
]);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Only "Motorola" smartphones
results = index.search('smartphone', {
filters: 'brand:Motorola'
})
# Only "LG" or "Samsung" smartphones
results2 = index.search('smartphone', {
filters: 'brand:LG OR brand:Samsung'
})
# Everything but "Apple" smartphones
results3 = index.search('smartphone', {
filters: 'NOT brand:Apple'
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| // Only “Motorola” smartphones
index.search('smartphone', {
filters: 'brand:Motorola'
}).then(({ hits }) => {
console.log(hits);
});
// Only “LG” or “Samsung” smartphones
index.search('smartphone', {
filters: 'brand:LG OR brand:Samsung'
}).then(({ hits }) => {
console.log(hits);
});
// Everything but “Apple” smartphones
index.search('smartphone', {
filters: 'NOT brand:Apple'
}).then(({ hits }) => {
console.log(hits);
});
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Only “Motorola” smartphones
results = index.search('smartphone', {
'filters': 'brand:Motorola'
})
# Only “LG” or “Samsung” smartphones
results2 = index.search('smartphone', {
'filters': 'brand:LG OR brand:Samsung'
})
# Everything but “Apple” smartphones
results3 = index.search('smartphone', {
'filters': 'NOT brand:Apple'
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // Only “Motorola” smartphones
let query = Query(query: "smartphone")
query.filters = "brand:Motorola"
// Only “LG” or “Samsung” smartphones
let query2 = Query(query: "smartphone")
query2.filters = "brand:LG OR brand:Samsung"
// Everything but “Apple” smartphones
let query3 = Query(query: "smartphone")
query3.filters = "NOT brand:Apple"
index.search(query, completionHandler: { (res, error) in
print(res)
})
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // Only “Motorola” smartphones
index.search(
new Query("smartphone")
.setFilters("brand:Motorola")
);
// Only “LG” or “Samsung” smartphones
index.search(
new Query("smartphone")
.setFilters("brand:LG OR brand:Samsung")
);
// Everything but “Apple” smartphones
index.search(
new Query("smartphone")
.setFilters("NOT brand:Apple")
);
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| // Only “Motorola” smartphones
index.Search(new Query("smartphone") {
Filters = "brand:Motorola"
});
// Only “LG” or “Samsung” smartphones
index.Search(new Query("smartphone") {
Filters = "brand:LG OR brand:Samsung"
});
// Everything but “Apple” smartphones
index.Search(new Query("smartphone") {
Filters = "NOT brand:Apple"
});
|
1
2
3
4
5
6
7
8
9
10
11
| // Only “Motorola” smartphones
index.search(new Query("smartphone")
.setFilters("brand:Motorola"));
// Only “LG” or “Samsung” smartphones
index.search(new Query("smartphone")
.setFilters("brand:LG OR brand:Samsung"));
// Everything but “Apple” smartphones
index.search(new Query("smartphone")
.setFilters("NOT brand:Apple"));
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // Ony "Motorola" smartphones
res, err := index.Search(
"smartphone",
opt.Filters("brand:Motorola"),
)
// Ony "LG" or "Samsung" smartphones
res, err := index.Search(
"smartphone",
opt.Filters("brand:LG OR brand:Samsung"),
)
// Everything but "Apple" smartphones
res, err := index.Search(
"smartphone",
opt.Filters("NOT brand:Apple"),
)
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
| // Only “Motorola” smartphones
index.search(query("smartphone") {
filters {
and {
facet("brand", "Motorola")
}
}
})
// Only “LG” or “Samsung” smartphones
index.search(query("smartphone") {
filters {
orFacet {
facet("brand", "Motorola")
facet("brand", "Samsung")
}
}
})
// Everything but “Apple” smartphones
index.search(query("smartphone") {
filters {
and {
facet("brand", "Apple", isNegated = true)
}
}
})
|
Using the dashboard
Regarding filters, you can’t set them directly in the dashboard since you can only filter at query time. Yet, you can test for specific filters in the dashboard before using them in your search code.
- Go to your dashboard and select your index. This should take you automatically to the Browse section.
- Click the “Add Query Parameter” button, which is just below the search bar.
- Go to the Custom tab.
- Add your filter as JSON:
{ "filters": "brand:Motorola" }
or { "filters": "brand:LG OR brand:Samsung" }
or { "filters": "NOT brand:Apple" }
.
- Click “Apply”.
Note that you can alternatively use facet filters. Click the “Add Query Parameter” button, go to the Filters tab and enter your targeted facet filter(s).