Skip to main content

Usage

Quick Start

Add the Searchable trait to your model as usual, then build a search endpoint:

use Foxws\ScoutBuilder\AllowedFilter;
use Foxws\ScoutBuilder\AllowedSort;
use Foxws\ScoutBuilder\ScoutBuilder;

$results = ScoutBuilder::for(Post::class, $request)
->allowedFilters(
AllowedFilter::exact('status'),
AllowedFilter::in('tags'),
AllowedFilter::dynamicOperator('price'),
)
->allowedSorts(
AllowedSort::latest('recent', 'published_at'),
AllowedSort::field('title'),
)
->defaultSort('-recent')
->get();

This reads directly from the incoming $request:

ParameterExample
Search query?query=laravel
Exact filter?filter[status]=published
Multi-value filter?filter[tags]=php,laravel
Operator filter?filter[price]=gte:100
Sort?sort=-recent,title
Paginate?page[number]=2&page[size]=15

See Pagination for the full jsonPaginate() reference.

Wrapping an Existing Scout Builder

$builder = Post::search('laravel')->where('is_published', true);

$results = ScoutBuilder::for($builder, $request)
->allowedFilters(AllowedFilter::exact('status'))
->get();

Facade

use Foxws\ScoutBuilder\Facades\ScoutBuilder;

$results = ScoutBuilder::for(Post::class, $request)
->allowedFilters(AllowedFilter::scope('published'))
->get();

Differences from spatie/laravel-query-builder

Featurespatie/laravel-query-builderfoxws/laravel-scout-builder
Underlying builderEloquent BuilderScout Builder
AllowedInclude✅ via Scout query() callback (database/collection drivers)
FiltersPartial, FiltersBeginsWith, etc.— (text search handled by Scout itself)
AllowedFilter::operator()via FiltersOperator✅ first-class with FilterOperator enum
AllowedFilter::dynamicOperator()✅ colon-token + array payload
AllowedFilter::notIn()
AllowedSort::latest() / oldest()
jsonPaginate()✅ (Eloquent only)✅ JSON:API page[number]/page[size]
Engine awarenessScoutDriver + EngineFeature enums
Request scalar castingraw strings✅ auto-casts 'true', '42', 'null', etc.