Add full-text search to Eloquent models with the official Scout package. Supports Meilisearch, Algolia, Typesense, and a built-in database engine, with automatic index syncing via model observers.
Laravel Scout provides a simple, driver-based solution for adding full-text search to your Eloquent models. Using model observers, Scout will automatically keep your search indexes in sync with your Eloquent records.Scout ships with a built-in database engine that uses MySQL / PostgreSQL full-text indexes and LIKE clauses to search your existing database — no external service required. For large-scale production workloads requiring typo tolerance, faceted filtering, or geo-search, external engines are available.
Finally, add the Laravel\Scout\Searchable trait to the model you want to make searchable. This trait registers a model observer that keeps the model in sync with your search driver:
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;use Laravel\Scout\Searchable;class Post extends Model{ use Searchable;}
When using an engine other than database or collection, you should strongly consider configuring a queue driver before using Scout. Running a queue worker allows Scout to queue all index sync operations in the background, providing much better response times for your web interface.Set the queue option in config/scout.php to true:
'queue' => true,
You can also specify the connection and queue name:
Meilisearch requires you to pre-define filterableAttributes for columns you plan to use with Scout’s where method, and sortableAttributes for columns you plan to sort by:
These built-in engines require no external service.The database engine uses MySQL / PostgreSQL full-text indexes and LIKE clauses. It is the recommended starting point for most applications:
SCOUT_DRIVER=database
The collection engine retrieves all records from your database and filters them in PHP, so it works with any database Laravel supports, including SQLite. It is intended for local development, small datasets, and tests:
SCOUT_DRIVER=collection
The database engine searches your database tables directly — no separate indexing step is required.
By default, the entire toArray form of a model is persisted to its search index. Override toSearchableArray to control which data is synchronized:
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;use Laravel\Scout\Searchable;class Post extends Model{ use Searchable; /** * Get the indexable data array for the model. * * @return array<string, mixed> */ public function toSearchableArray(): array { $array = $this->toArray(); // Customize the data array... return $array; }}
The commands in this section are primarily relevant when using a third-party engine (Algolia, Meilisearch, or Typesense). The database engine does not require manual index management.
Add filter conditions to your search query with where:
use App\Models\Order;// Equality filter$orders = Order::search('Star Trek')->where('user_id', 1)->get();// Match any value in array$orders = Order::search('Star Trek')->whereIn('status', ['open', 'paid'])->get();// Exclude values in array$orders = Order::search('Star Trek')->whereNotIn('status', ['closed'])->get();
When using Meilisearch, you must configure filterable attributes before using Scout’s where clauses.
Customize the Eloquent query for the results using query:
Scout retrieves IDs from the search engine and then fetches the models via Eloquent. To avoid N+1 queries, use the query method to eager load relationships:
To eager load relationships during batch import, define makeAllSearchableUsing on the model:
use Illuminate\Database\Eloquent\Builder;protected function makeAllSearchableUsing(Builder $query): Builder{ return $query->with('author');}
makeAllSearchableUsing may not be applicable when using a queue to batch import models, because relationships are not restored when model collections are processed by jobs.
If the built-in engines don’t meet your needs, you can write your own. Extend the Laravel\Scout\Engines\Engine abstract class and implement its eight required methods:
use Laravel\Scout\Builder;abstract public function update($models);abstract public function delete($models);abstract public function search(Builder $builder);abstract public function paginate(Builder $builder, $perPage, $page);abstract public function mapIds($results);abstract public function map(Builder $builder, $results, $model);abstract public function getTotalCount($results);abstract public function flush($model);
Review Laravel\Scout\Engines\AlgoliaEngine for a reference implementation.Register your custom engine in the boot method of App\Providers\AppServiceProvider:
use App\ScoutExtensions\MySqlSearchEngine;use Laravel\Scout\EngineManager;public function boot(): void{ resolve(EngineManager::class)->extend('mysql', function () { return new MySqlSearchEngine; });}
Then specify it as the driver in config/scout.php: