Laravel Scout provides a convenient way to integrate search functionality into your application, but when using Typesense, you might notice that facets aren’t included in the default search method.
This article demonstrates how to properly add facet filters to your Typesense searches in Laravel Scout.
Basic Implementation
Here’s a simplified implementation that shows how to add facets to your Laravel Scout search with Typesense by using the raw method:
public function index()
{
// Start with a basic search query
$query = Product::search('my searchterm');
// Prepare filter conditions
$filterBy = [];
// For example, price larger than 100 or your own custom set filter
$filterBy[] = 'price:>=100';
// Apply Typesense-specific options if you'd like
$query->options([
'query_by' => 'name',
'filter_by' => implode(' && ', $filterBy),
'facet_by' => 'brand,category,price', // Request these facets from Typesense, make sure that those facets are available
'sort_by' => $request->input('sort_by', 'relevance:desc')
]);
// Get paginated results
$results = $query->paginate(24);
// Add facet counts to the paginated results
$results->facetCounts = $this->getFacets($query);
return $results;
}
/**
* Get facets from the Typesense search results
*/
private function getFacets($query)
{
$raw = $query->raw();
return $raw['facet_counts'] ?? [];
}
Optional: Reformatting Facets for Easier Use
You can also reformat the facets to make them easier to work with in your application:
/**
* Reformat Typesense facets for easier use
*
* @param array $facets The raw facet counts from Typesense
* @return \Illuminate\Support\Collection
*/
private function reformatFacets(array $facets): \Illuminate\Support\Collection
{
$result = collect();
foreach ($facets as $facet) {
$fieldName = $facet['field_name'] ?? null;
if (!$fieldName) {
continue;
}
$counts = collect($facet['counts'] ?? [])->map(function($item) {
return [
'value' => $item['value'],
'count' => $item['count']
];
});
$result[$fieldName] = $counts;
}
return $result;
}
Using the Facets in Your Application
To use the reformatted facets, simply modify the previous search method:
// Get paginated results
$results = $query->paginate(24);
// Get raw facet counts from Typesense
$facets = $query->raw()['facet_counts'] ?? [];
// Add reformatted facets to the paginated results
$results->facetCounts = $this->reformatFacets($facets);
return $results;
Key Points to Remember
- Use the
facet_by
option to specify which fields you want facets for - Access the raw facet data from the search query with
$query->raw()['facet_counts']
- Consider reformatting the facets to make them easier to work with in your application
- Attach the facets to your paginated results so they’re accessible in your views
By implementing these techniques, you can easily add powerful faceted filtering capabilities to your Laravel application with Typesense, allowing users to refine their search results by various criteria.