Paquete oficial que añade búsqueda de texto completo a los modelos Eloquent. Es compatible con Meilisearch, Algolia, Typesense y el motor basado en base de datos, y sincroniza los índices automáticamente mediante observers.
Laravel Scout es una solución sencilla basada en drivers para añadir búsqueda de texto completo a los modelos Eloquent. Utiliza observers para mantener sincronizados los registros Eloquent con los índices de búsqueda.Scout incluye un motor database integrado que utiliza índices full-text de MySQL/PostgreSQL y la cláusula LIKE para buscar directamente sobre la base de datos, sin necesidad de servicios externos. En entornos de producción grandes en los que necesitas tolerancia a erratas, faceting o búsqueda geográfica, los motores externos son de gran ayuda.
Por último, añade el trait Laravel\Scout\Searchable a los modelos que quieres hacer buscables. El trait registra los observers y activa la sincronización automática con el driver de búsqueda.
<?phpnamespace App\Models;use Illuminate\Database\Eloquent\Model;use Laravel\Scout\Searchable;class Post extends Model{ use Searchable;}
Si usas cualquier motor distinto de database o collection, es muy recomendable configurar un driver de colas antes de utilizar Scout. Con un worker corriendo, la sincronización del índice se ejecuta en segundo plano y la interfaz web es mucho más ágil.Pon queue a true en config/scout.php.
En aplicaciones con mucha escritura te puede interesar evitar encolar varias veces el mismo job para el mismo modelo. Registra las clases MakeSearchableUniquely y RemoveFromSearchUniquely en config/scout.php (normalmente en el método boot de un service provider).
use Laravel\Scout\Jobs\MakeSearchableUniquely;use Laravel\Scout\Jobs\RemoveFromSearchUniquely;use Laravel\Scout\Scout;Scout::makeSearchableUsing(MakeSearchableUniquely::class);Scout::removeFromSearchUsing(RemoveFromSearchUniquely::class);
Estos jobs se apoyan en los locks de jobs únicos de Laravel para no despachar operaciones duplicadas sobre el mismo modelo.
Con Meilisearch necesitas declarar de antemano en filterableAttributes las columnas por las que vas a filtrar con where(), y en sortableAttributes las que usarás con orderBy().
Ideales si quieres añadir búsqueda sin servicios externos.El motor database aprovecha los índices full-text y LIKE de MySQL/PostgreSQL. Suficiente para la mayoría de aplicaciones.
SCOUT_DRIVER=database
El motor collection filtra en PHP, así que funciona con cualquier base de datos soportada por Laravel, incluida SQLite. Ideal para desarrollo, tests y conjuntos pequeños.
SCOUT_DRIVER=collection
Con el motor database no necesitas gestionar índices manualmente: busca directamente contra la tabla.
Los comandos de esta sección son relevantes principalmente para motores externos (Algolia, Meilisearch, Typesense…). En el motor database no hace falta gestionar el índice.
use App\Models\Order;// Igualdad$orders = Order::search('Star Trek')->where('user_id', 1)->get();// Alguno de los valores$orders = Order::search('Star Trek')->whereIn('status', ['open', 'paid'])->get();// Ninguno de los valores$orders = Order::search('Star Trek')->whereNotIn('status', ['closed'])->get();
Con Meilisearch necesitas declarar los atributos filtrables antes de usar where.
También puedes personalizar la query Eloquent con query.
Para cargar relaciones durante la importación masiva, define makeAllSearchableUsing.
use Illuminate\Database\Eloquent\Builder;protected function makeAllSearchableUsing(Builder $query): Builder{ return $query->with('author');}
makeAllSearchableUsing puede no aplicarse durante importaciones por cola: cuando el job procesa la colección de modelos, las relaciones no se restauran.
Si ninguno de los motores integrados encaja, puedes implementar el tuyo. Debes extender la clase abstracta Laravel\Scout\Engines\Engine e implementar los ocho métodos siguientes.
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);
Como referencia, revisa la clase Laravel\Scout\Engines\AlgoliaEngine.Registra tu motor en el método boot de App\Providers\AppServiceProvider.
use App\ScoutExtensions\MySqlSearchEngine;use Laravel\Scout\EngineManager;public function boot(): void{ resolve(EngineManager::class)->extend('mysql', function () { return new MySqlSearchEngine; });}