Uso de Laravel Scout para habilitar la búsqueda de texto completo
Publicado: 2023-05-08El marco de Laravel se ha convertido en un recurso de referencia para los desarrolladores que crean servicios web.
Como herramienta de código abierto, Laravel ofrece una gran variedad de funcionalidades listas para usar que permiten a los desarrolladores crear aplicaciones sólidas y funcionales.
Entre sus ofertas se encuentra Laravel Scout, una biblioteca para administrar los índices de búsqueda de su aplicación. Su flexibilidad permite a los desarrolladores ajustar las configuraciones y seleccionar controladores de Algolia, Meilisearch, MySQL o Postgres para almacenar los índices.
Aquí, exploraremos esta herramienta en profundidad, enseñándole cómo agregar soporte de búsqueda de texto completo a una aplicación Laravel a través del controlador. Modelará una aplicación de demostración de Laravel para almacenar el nombre de los trenes de maquetas y luego usará Laravel Scout para agregar una búsqueda a la aplicación.
requisitos previos
Para seguir, debe tener:
- El compilador PHP instalado en su computadora. Este tutorial utiliza PHP versión 8.1.
- El motor Docker o Docker Desktop instalado en su computadora
- Una cuenta en la nube de Algolia, que puede crear de forma gratuita
Cómo instalar Scout en un proyecto de Laravel
Para usar Scout, primero debe crear una aplicación Laravel en la que desee agregar la función de búsqueda. El script Laravel-Scout Bash contiene los comandos para generar una aplicación Laravel dentro de un contenedor Docker. El uso de Docker significa que no necesita instalar software de soporte adicional, como una base de datos MySQL.
El script de Laravel-scout utiliza el lenguaje de scripting Bash, por lo que debe ejecutarlo en un entorno Linux. Si está ejecutando Windows, asegúrese de configurar el Subsistema de Windows para Linux (WSL).
Si usa WSL, ejecute el siguiente comando en su terminal para configurar su distribución de Linux preferida.
wsl -s ubuntu
Luego, navegue a la ubicación en su computadora donde le gustaría colocar el proyecto. El script de Laravel-Scout generará un directorio de proyecto aquí. En el siguiente ejemplo, el script Laravel-Scout crearía un directorio dentro del directorio del escritorio .
cd /desktop
Ejecute el siguiente comando para ejecutar el script Laravel-Scout. Montará una aplicación dockerizada con el código repetitivo necesario.
curl -s https://laravel.build/laravel-scout-app | bash
Después de la ejecución, cambie su directorio usando cd laravel-scout-app
. Luego, ejecute el comando sail-up
dentro de la carpeta del proyecto para iniciar los contenedores de Docker para su aplicación.
Nota: en muchas distribuciones de Linux, es posible que deba ejecutar el siguiente comando con el comando sudo
para iniciar privilegios elevados.
./vendor/bin/sail up
Es posible que encuentre un error:
Para resolver esto, use la variable APP_PORT
para especificar un puerto dentro del comando sail up
:
APP_PORT=3001 ./vendor/bin/sail up
A continuación, ejecute el siguiente comando para ejecutar la aplicación a través de Artisan en el servidor PHP.
php artisan serve
Desde su navegador web, navegue hasta la aplicación en ejecución en http://127.0.0.1:8000. La aplicación mostrará la página de bienvenida de Laravel en la ruta predeterminada.
Cómo agregar Laravel Scout a la aplicación
En su terminal, ingrese el comando para habilitar el administrador de paquetes Composer PHP para agregar Laravel Scout al proyecto.
composer require laravel/scout
Luego, publique el archivo de configuración de Scout usando el comando vendor:publish. El comando publicará el archivo de configuración scout.php
en el directorio de configuración de su aplicación.
php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
Ahora, modifique el archivo repetitivo .env para que contenga un valor booleano SCOUT_QUEUE
.
El valor SCOUT_QUEUE
permitirá a Scout poner en cola las operaciones, proporcionando mejores tiempos de respuesta. Sin él, los controladores Scout como Meilisearch no reflejarán nuevos registros de inmediato.
SCOUT_QUEUE=true
Además, modifique la variable DB_HOST
en el archivo .env para que apunte a su host local para usar la base de datos MySQL dentro de los contenedores de Docker.
DB_HOST=127.0.0.1
Cómo marcar un modelo y configurar el índice
Scout no habilita los modelos de datos de búsqueda de forma predeterminada. Debe marcar explícitamente un modelo como apto para búsquedas utilizando su rasgo Laravel\Scout\Searchable
.
Comenzará creando un modelo de datos para una aplicación Train
de demostración y marcándolo como apto para búsquedas.
Cómo crear un modelo
Para la aplicación Train
, querrá almacenar los nombres de marcador de posición de cada tren disponible.
Ejecute el siguiente comando de Artisan para generar la migración y asígnele el nombre create_trains_table
.
php artisan make:migration create_trains_table
La migración se generará en un archivo cuyo nombre combina el nombre especificado y la marca de tiempo actual.
Abra el archivo de migración ubicado en el directorio base de datos/migraciones/ .
Para agregar una columna de título, agregue el siguiente código después de la columna id()
en la línea 17. El código agregará una columna de título.
$table->string('title');
Para aplicar la migración, ejecute el siguiente comando.
php artisan migrate
Después de ejecutar las migraciones de la base de datos, cree un archivo llamado Train.php en el directorio app/Models/ .
Cómo agregar el rasgo de búsqueda de LaravelScout
Marque el modelo Train
para la búsqueda agregando el rasgo Laravel\Scout\Searchable
al modelo, como se muestra a continuación.
<?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Train extends Model { use Searchable; public $fillable = ['title'];
Además, debe configurar los índices de búsqueda anulando el método searchable
. El comportamiento predeterminado de Scout persistirá en el modelo para que coincida con el nombre de la tabla del modelo.
Entonces, agregue el siguiente código al archivo Train.php debajo del código del bloque anterior.
/** * Retrieve the index name for the model. * * @return string */ public function searchableAs() { return 'trains_index'; } }
Cómo usar Algolia con Scout
Para la primera búsqueda de texto completo con Laravel Scout, utilizará el controlador Algolia. Algolia es una plataforma de software como servicio (SaaS) que se utiliza para buscar en grandes cantidades de datos. Proporciona un panel web para que los desarrolladores administren sus índices de búsqueda y una API sólida a la que puede acceder a través de un kit de desarrollo de software (SDK) en su lenguaje de programación preferido.
Dentro de la aplicación Laravel, utilizará el paquete de cliente Algolia para PHP.
Cómo configurar Algolia
Primero, debe instalar el paquete de cliente de búsqueda PHP de Algolia para su aplicación.
Ejecute el siguiente comando.
composer require algolia/algoliasearch-client-php
A continuación, debe establecer sus credenciales de ID de aplicación y clave de API secreta de Algolia en el archivo .env .
Usando su navegador web, navegue a su panel de control de Algolia para obtener las credenciales de la ID de la aplicación y la clave secreta de la API.
Haga clic en Configuración en la parte inferior de la barra lateral izquierda para navegar a la página Configuración .
A continuación, haga clic en Claves de API en la sección Equipo y acceso de la página Configuración para ver las claves de su cuenta de Algolia.
En la página Claves de API, anote los valores de ID de aplicación y Clave de API de administración . Utilizará estas credenciales para autenticar la conexión entre la aplicación Laravel y Algolia.
Agregue el código a continuación a su archivo .env usando su editor de código y reemplace los marcadores de posición con los secretos de API de Algolia correspondientes.
ALGOLIA_APP_ID=APPLICATION_ID ALGOLIA_SECRET=ADMIN_API_KEY
Además, reemplace la variable SCOUT_DRIVER
con el siguiente código para cambiar el valor de meilisearch
a algolia
. Cambiar este valor le indicará a Scout que use el controlador Algolia.
SCOUT_DRIVER=algolia
Cómo crear los controladores de aplicaciones
Dentro del directorio app/Http/Controllers/ , cree un archivo TrainSearchController.php para almacenar un controlador para la aplicación. El controlador listará y agregará datos al modelo Train
.
Agregue el siguiente bloque de código en el archivo TrainSearchController.php para construir el controlador.
<?php namespace App\Http\Controllers; use Illuminate\Http\Request; use App\Http\Requests; use App\Models\Train; class TrainSearchController extends Controller { /** * Get the index name for the model. * * @return string */ public function index(Request $request) { if($request->has('titlesearch')){ $trains = Train::search($request->titlesearch) ->paginate(6); }else{ $trains = Train::paginate(6); } return view('Train-search',compact('trains')); } /** * Get the index name for the model. * * @return string */ public function create(Request $request) { $this->validate($request,['title'=>'required']); $trains = Train::create($request->all()); return back(); } }
Cómo crear las rutas de aplicación
En este paso, creará las rutas para enumerar y agregar nuevos trenes a la base de datos.
Abra su archivo route/web.php y reemplace el código existente con el bloque a continuación.
<?php use Illuminate\Support\Facades\Route; use App\Http\Controllers\TrainSearchController; Route::get('/', function () { return view('welcome'); }); Route::get('trains-lists', [TrainSearchController::class, 'index']) -> name ('trains-lists'); Route::post('create-item', [TrainSearchController::class, 'create']) -> name ('create-item');
El código anterior define dos rutas en la aplicación. La solicitud GET
para la ruta /trains-lists
enumera todos los datos de trenes almacenados. La solicitud POST
para la ruta /create-item
crea nuevos datos de tren.
Cómo crear las vistas de la aplicación
Cree un archivo dentro del directorio resources/views/ y asígnele el nombre Train-search.blade.php . El archivo mostrará la interfaz de usuario para la función de búsqueda.
Agregue el contenido del bloque de código a continuación en el archivo Train-search.blade.php para crear una sola página para la función de búsqueda.
<!DOCTYPE html> <html> <head> <title>Laravel - Laravel Scout Algolia Search Example</title> <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css"> </head> <body> <div class="container"> <h2 class="text-bold">Laravel Full-Text Search Using Scout </h2><br/> <form method="POST" action="{{ route('create-item') }}" autocomplete="off"> @if(count($errors)) <div class="alert alert-danger"> <strong>Whoops!</strong> There is an error with your input. <br/> <ul> @foreach($errors->all() as $error) <li>{{ $error }}</li> @endforeach </ul> </div> @endif <input type="hidden" name="_token" value="{{ csrf_token() }}"> <div class="row"> <div class="col-md-6"> <div class="form-group {{ $errors->has('title') ? 'has-error' : '' }}"> <input type="text" name="title" class="form-control" placeholder="Enter Title" value="{{ old('title') }}"> <span class="text-danger">{{ $errors->first('title') }}</span> </div> </div> <div class="col-md-6"> <div class="form-group"> <button class="btn btn-primary">Create New Train</button> </div> </div> </div> </form> <div class="panel panel-primary"> <div class="panel-heading">Train Management</div> <div class="panel-body"> <form method="GET" action="{{ route('trains-lists') }}"> <div class="row"> <div class="col-md-6"> <div class="form-group"> <input type="text" name="titlesearch" class="form-control" placeholder="Enter Title For Search" value="{{ old('titlesearch') }}"> </div> </div> <div class="col-md-6"> <div class="form-group"> <button class="btn btn-primary">Search</button> </div> </div> </div> </form> <table class="table"> <thead> <th>Id</th> <th>Train Title</th> <th>Creation Date</th> <th>Updated Date</th> </thead> <tbody> @if($trains->count()) @foreach($trains as $key => $item) <tr> <td>{{ ++$key }}</td> <td>{{ $item->title }}</td> <td>{{ $item->created_at }}</td> <td>{{ $item->updated_at }}</td> </tr> @endforeach @else <tr> <td colspan="4">No train data available</td> </tr> @endif </tbody> </table> {{ $trains->links() }} </div> </div> </div> </body> </html>
El código HTML anterior contiene un elemento de formulario con un campo de entrada y un botón para escribir el título de un tren antes de guardarlo en la base de datos. El código también tiene una tabla HTML que muestra los detalles de id , title , created_at y updated_at de una entrada de tren dentro de la base de datos.
Cómo usar la búsqueda de Algolia
Para ver la página, vaya a http://127.0.0.1:8000/trains-lists desde su navegador web.
La base de datos está actualmente vacía, por lo que debe ingresar un título de un tren de demostración en el campo de entrada y hacer clic en Crear nuevo tren para guardarlo.
Para usar la función de búsqueda, escriba una palabra clave de cualquier título de tren guardado en el campo de entrada Ingresar título para buscar y haga clic en Buscar .
Como se muestra en la imagen a continuación, solo se mostrarán las entradas de búsqueda que contengan la palabra clave en sus títulos.
Meilisearch con Laravel Scout
Meilisearch es un motor de búsqueda de código abierto que se centra en la velocidad, el rendimiento y la mejora de la experiencia del desarrollador. Comparte varias características con Algolia, utilizando los mismos algoritmos, estructuras de datos e investigación, pero con un lenguaje de programación diferente.
Los desarrolladores pueden crear y autohospedar una instancia de Meilisearch dentro de su infraestructura local o en la nube. Meilisearch también tiene una oferta de nube beta similar a Algolia para desarrolladores que desean usar el producto sin administrar su infraestructura.
En el tutorial, ya tiene una instancia local de Meilisearch ejecutándose dentro de sus contenedores Docker. Ahora extenderá la funcionalidad de Laravel Scout para usar la instancia de Meilisearch.
Para agregar Meilisearch a la aplicación Laravel, ejecute el siguiente comando en su terminal de proyecto.
composer require meilisearch/meilisearch-php
A continuación, debe modificar las variables de Meilisearch dentro del archivo .env para configurarlo.
Reemplace las variables SCOUT_DRIVER
, MEILISEARCH_HOST
y MEILISEARCH_KEY
en el archivo .env con las siguientes.
SCOUT_DRIVER=meilisearch MEILISEARCH_HOST=http://127.0.0.1:7700 MEILISEARCH_KEY=LockKey
La clave SCOUT_DRIVER
especifica el controlador que debe usar Scout, mientras que MEILISEARCH_HOST
representa el dominio donde se ejecuta su instancia de Meilisearch. Aunque no es necesario durante el desarrollo, se recomienda agregar MEILISEARCH_KEY
en producción.
Nota: Comente el ID y el secreto de Algolia cuando use Meilisearch como su controlador preferido.
Después de completar las configuraciones de .env , debe indexar sus registros preexistentes usando el comando Artisan a continuación.
php artisan scout:import "App\Models\Train"
Laravel Scout con motor de base de datos
El motor de base de datos de Scout puede ser más adecuado para aplicaciones que utilizan bases de datos más pequeñas o que administran cargas de trabajo menos intensivas. Actualmente, el motor de la base de datos es compatible con PostgreSQL y MySQL.
Este motor utiliza cláusulas "where-like" e índices de texto completo en su base de datos existente, lo que le permite encontrar los resultados de búsqueda más relevantes. No necesita indexar sus registros cuando utiliza el motor de base de datos.
Para usar el motor de la base de datos, debe establecer su variable SCOUT_DRIVER
.env en la base de datos.
Abra el archivo .env dentro de la aplicación Laravel y cambie el valor de la variable SCOUT_DRIVER
.
SCOUT_DRIVER = database
Después de cambiar su controlador a la base de datos, Scout pasará a utilizar el motor de la base de datos para la búsqueda de texto completo.
Motor de colección con Laravel Scout
Además del motor de base de datos, Scout también ofrece un motor de recopilación. Este motor utiliza cláusulas de "dónde" y filtrado de colecciones para extraer los resultados de búsqueda más relevantes.
A diferencia del motor de base de datos, el motor de recopilación admite todas las bases de datos relacionales que también admite Laravel.
Puede utilizar el motor de recopilación estableciendo la variable de entorno SCOUT_DRIVER
en collection
o especificando manualmente el controlador de recopilación en el archivo de configuración de Scout.
SCOUT_DRIVER = collection
Explorador con Elasticsearch
Con la fuerza de las consultas de Elasticsearch, Explorer es un controlador de Elasticsearch moderno para Laravel Scout. Ofrece un controlador Scout compatible y beneficios como almacenamiento, búsqueda y análisis de grandes cantidades de datos en tiempo real. Elasticsearch con Laravel ofrece resultados en milisegundos.
Para usar el controlador de Elasticsearch Explorer en su aplicación Laravel, deberá configurar el archivo repetitivo docker-compose.yml que generó el script Laravel-Scout. Agregará las configuraciones adicionales para Elasticsearch y reiniciará los contenedores.
Abra su archivo docker-compose.yml y reemplace su contenido con lo siguiente.
# For more information: https://laravel.com/docs/sail version: '3' services: laravel.test: build: context: ./vendor/laravel/sail/runtimes/8.1 dockerfile: Dockerfile args: WWWGROUP: '${WWWGROUP}' image: sail-8.1/app extra_hosts: - 'host.docker.internal:host-gateway' ports: - '${APP_PORT:-80}:80' - '${VITE_PORT:-5173}:${VITE_PORT:-5173}' environment: WWWUSER: '${WWWUSER}' LARAVEL_SAIL: 1 XDEBUG_MODE: '${SAIL_XDEBUG_MODE:-off}' XDEBUG_CONFIG: '${SAIL_XDEBUG_CONFIG:-client_host=host.docker.internal}' volumes: - '.:/var/www/html' networks: - sail depends_on: - mysql - redis - meilisearch - mailhog - selenium - pgsql - elasticsearch mysql: image: 'mysql/mysql-server:8.0' ports: - '${FORWARD_DB_PORT:-3306}:3306' environment: MYSQL_ROOT_PASSWORD: '${DB_PASSWORD}' MYSQL_ROOT_HOST: "%" MYSQL_DATABASE: '${DB_DATABASE}' MYSQL_USER: '${DB_USERNAME}' MYSQL_PASSWORD: '${DB_PASSWORD}' MYSQL_ALLOW_EMPTY_PASSWORD: 1 volumes: - 'sail-mysql:/var/lib/mysql' - './vendor/laravel/sail/database/mysql/create-testing-database.sh:/docker-entrypoint-initdb.d/10-create-testing-database.sh' networks: - sail healthcheck: test: ["CMD", "mysqladmin", "ping", "-p${DB_PASSWORD}"] retries: 3 timeout: 5s elasticsearch: image: 'elasticsearch:7.13.4' environment: - discovery.type=single-node ports: - '9200:9200' - '9300:9300' volumes: - 'sailelasticsearch:/usr/share/elasticsearch/data' networks: - sail kibana: image: 'kibana:7.13.4' environment: - elasticsearch.hosts=http://elasticsearch:9200 ports: - '5601:5601' networks: - sail depends_on: - elasticsearch redis: image: 'redis:alpine' ports: - '${FORWARD_REDIS_PORT:-6379}:6379' volumes: - 'sail-redis:/data' networks: - sail healthcheck: test: ["CMD", "redis-cli", "ping"] retries: 3 timeout: 5s pgsql: image: 'postgres:13' ports: - '${FORWARD_DB_PORT:-5432}:5432' environment: PGPASSWORD: '${DB_PASSWORD:-secret}' POSTGRES_DB: '${DB_DATABASE}' POSTGRES_USER: '${DB_USERNAME}' POSTGRES_PASSWORD: '${DB_PASSWORD:-secret}' volumes: - 'sailpgsql:/var/lib/postgresql/data' networks: - sail healthcheck: test: ["CMD", "pg_isready", "-q", "-d", "${DB_DATABASE}", "-U", "${DB_USERNAME}"] retries: 3 timeout: 5s meilisearch: image: 'getmeili/meilisearch:latest' ports: - '${FORWARD_MEILISEARCH_PORT:-7700}:7700' volumes: - 'sail-meilisearch:/meili_data' networks: - sail healthcheck: test: ["CMD", "wget", "--no-verbose", "--spider", "http://localhost:7700/health"] retries: 3 timeout: 5s mailhog: image: 'mailhog/mailhog:latest' ports: - '${FORWARD_MAILHOG_PORT:-1025}:1025' - '${FORWARD_MAILHOG_DASHBOARD_PORT:-8025}:8025' networks: - sail selenium: image: 'selenium/standalone-chrome' extra_hosts: - 'host.docker.internal:host-gateway' volumes: - '/dev/shm:/dev/shm' networks: - sail networks: sail: driver: bridge volumes: sail-mysql: driver: local sail-redis: driver: local sail-meilisearch: driver: local sailpgsql: driver: local sailelasticsearch: driver: local
A continuación, ejecute el siguiente comando para extraer la nueva imagen de Elasticsearch que agregó al archivo docker-compose.yml .
docker-compose up
Luego, ejecute el comando Composer a continuación para instalar Explorer en el proyecto.
composer require jeroen-g/explorer
También necesita crear un archivo de configuración para el controlador Explorer.
Ejecute el comando Artisan a continuación para generar un archivo explorer.config para almacenar las configuraciones.
php artisan vendor:publish --tag=explorer.config
El archivo de configuración generado anteriormente estará disponible en el directorio /config .
En su archivo config/explorer.php , puede hacer referencia a su modelo usando la clave indexes
.
'indexes' => [ \App\Models\Train::class ],
Cambie el valor de la variable SCOUT_DRIVER
dentro del archivo .env a elastic
para configurar Scout para usar el controlador Explorer.
SCOUT_DRIVER = elastic
En este punto, usará Explorer dentro del modelo Train
implementando la interfaz de Explorer y anulando el método mappableAs()
.
Abra el archivo Train.php dentro del directorio Aplicación > Modelos y reemplace el código existente con el siguiente código.
<?php namespace App\Models; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use JeroenG\Explorer\Application\Explored; use Laravel\Scout\Searchable; class Train extends Model implements Explored { use HasFactory; use Searchable; protected $fillable = ['title']; public function mappableAs(): array { return [ 'id'=>$this->Id, 'title' => $this->title, ]; } }
Con el código que agregó anteriormente, ahora puede usar Explorer para buscar texto dentro del modelo Train
.
Resumen
Para los desarrolladores de PHP, Laravel y complementos como Scout facilitan la integración de una funcionalidad de búsqueda de texto completo rápida y sólida. Con el motor de base de datos, el motor de recopilación y las capacidades de Meilisearch y Elasticsearch, puede interactuar con la base de datos de su aplicación e implementar mecanismos de búsqueda avanzada en solo milisegundos.
Administrar y actualizar su base de datos sin problemas significa que sus usuarios reciben una experiencia óptima mientras su código permanece limpio y eficiente.
Con nuestras soluciones de alojamiento de aplicaciones y bases de datos, Kinsta es su ventanilla única para todas sus necesidades modernas de desarrollo de Laravel. Los primeros $20 son por nuestra cuenta.