Usando o Laravel Scout para ativar a pesquisa de texto completo

Publicados: 2023-05-08

A estrutura Laravel tornou-se um recurso obrigatório para desenvolvedores que constroem serviços da web.

Como uma ferramenta de código aberto, o Laravel oferece uma infinidade de funcionalidades prontas para uso que permitem aos desenvolvedores criar aplicativos robustos e funcionais.

Entre suas ofertas está o Laravel Scout, uma biblioteca para gerenciar os índices de busca de sua aplicação. Sua flexibilidade permite que os desenvolvedores ajustem as configurações e selecionem os drivers Algolia, Meilisearch, MySQL ou Postgres para armazenar os índices.

Aqui, exploraremos essa ferramenta em profundidade, ensinando como adicionar suporte de pesquisa de texto completo a um aplicativo Laravel por meio do driver. Você modelará um aplicativo Laravel de demonstração para armazenar o nome dos trens de maquete e, em seguida, usará o Laravel Scout para adicionar uma pesquisa ao aplicativo.

Pré-requisitos

Para acompanhar, você deve ter:

  • O compilador PHP instalado em seu computador. Este tutorial usa PHP versão 8.1.
  • O mecanismo do Docker ou o Docker Desktop instalado em seu computador
  • Uma conta na nuvem da Algolia, que você pode criar gratuitamente
Quer tornar seu aplicativo mais fácil de usar? Tente adicionar um suporte de pesquisa de texto completo! Veja como com o Laravel Scout ️ Click to Tweet

Como instalar o Scout em um projeto Laravel

Para usar o Scout, você deve primeiro criar um aplicativo Laravel onde pretende adicionar a funcionalidade de pesquisa. O script Laravel-Scout Bash contém os comandos para gerar um aplicativo Laravel dentro de um contêiner Docker. Usar o Docker significa que você não precisa instalar software de suporte adicional, como um banco de dados MySQL.

O script Laravel-scout usa a linguagem de script Bash, então você deve executá-lo em um ambiente Linux. Se você estiver executando o Windows, certifique-se de configurar o Windows Subsystem for Linux (WSL).

Se estiver usando WSL, execute o seguinte comando em seu terminal para definir sua distribuição Linux preferida.

 wsl -s ubuntu

Em seguida, navegue até o local em seu computador onde você gostaria de colocar o projeto. O script Laravel-Scout irá gerar um diretório de projeto aqui. No exemplo abaixo, o script Laravel-Scout criaria um diretório dentro do diretório desktop .

 cd /desktop

Execute o comando abaixo para executar o script Laravel-Scout. Ele fará o scaffold de um aplicativo Dockerizado com o código clichê necessário.

 curl -s https://laravel.build/laravel-scout-app | bash

Após a execução, altere seu diretório usando cd laravel-scout-app . Em seguida, execute o comando sail-up na pasta do projeto para iniciar os contêineres do Docker para seu aplicativo.

Observação: em muitas distribuições do Linux, pode ser necessário executar o comando abaixo com o comando sudo para iniciar privilégios elevados.

 ./vendor/bin/sail up

Você pode encontrar um erro:

Erro informando que a porta está alocada
Erro informando que a porta está alocada.

Para resolver isso, use a variável APP_PORT para especificar uma porta dentro do comando sail up :

 APP_PORT=3001 ./vendor/bin/sail up

Em seguida, execute o comando abaixo para executar o aplicativo por meio do Artisan no servidor PHP.

 php artisan serve
Servindo o aplicativo Laravel com Artisan
Servindo o aplicativo Laravel com Artisan

No navegador da Web, navegue até o aplicativo em execução em http://127.0.0.1:8000. O aplicativo exibirá a página de boas-vindas do Laravel na rota padrão.

Página de boas-vindas do aplicativo Laravel
Página de boas-vindas do aplicativo Laravel

Como adicionar Laravel Scout ao aplicativo

No seu terminal, insira o comando para permitir que o gerenciador de pacotes Composer PHP adicione o Laravel Scout ao projeto.

 composer require laravel/scout

Em seguida, publique o arquivo de configuração do Scout usando o comando vendor:publish. O comando publicará o arquivo de configuração scout.php no diretório de configuração do seu aplicativo.

 php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

Agora, modifique o arquivo clichê .env para conter um valor booleano SCOUT_QUEUE .

O valor SCOUT_QUEUE permitirá que o Scout enfileire as operações, fornecendo melhores tempos de resposta. Sem ele, os motoristas do Scout como o Meilisearch não refletirão novos recordes imediatamente.

 SCOUT_QUEUE=true

Além disso, modifique a variável DB_HOST no arquivo .env para apontar para seu host local para usar o banco de dados MySQL nos contêineres do Docker.

 DB_HOST=127.0.0.1

Como marcar um modelo e configurar o índice

O Scout não habilita modelos de dados pesquisáveis ​​por padrão. Você deve marcar explicitamente um modelo como pesquisável usando seu traço Laravel\Scout\Searchable .

Você começará criando um modelo de dados para um aplicativo Train de demonstração e marcando-o como pesquisável.

Como criar um modelo

Para o aplicativo Train , você desejará armazenar os nomes de espaço reservado de cada trem disponível.

Execute o comando Artisan abaixo para gerar a migração e nomeie-a create_trains_table .

 php artisan make:migration create_trains_table
Fazendo uma migração chamada create_trains_table
Fazendo uma migração chamada create_trains_table

A migração será gerada em um arquivo cujo nome combina o nome especificado e o timestamp atual.

Abra o arquivo de migração localizado no diretório database/migrations/ .

Para adicionar uma coluna de título, adicione o seguinte código após a coluna id() na linha 17. O código adicionará uma coluna de título.

 $table->string('title');

Para aplicar a migração, execute o comando abaixo.

 php artisan migrate
Aplicando a migração Artisan
Aplicando a migração Artisan

Depois de executar as migrações do banco de dados, crie um arquivo chamado Train.php no diretório app/Models/ .

Como adicionar o LaravelScoutSearchable Trait

Marque o modelo Train para pesquisa adicionando o traço Laravel\Scout\Searchable ao modelo, conforme mostrado abaixo.

 <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Laravel\Scout\Searchable; class Train extends Model { use Searchable; public $fillable = ['title'];

Além disso, você precisa configurar os índices de pesquisa substituindo o método searchable . O comportamento padrão do Scout persistiria no modelo para corresponder ao nome da tabela do modelo.

Portanto, adicione o seguinte código ao arquivo Train.php abaixo do código do bloco anterior.

 /** * Retrieve the index name for the model. * * @return string */ public function searchableAs() { return 'trains_index'; } }

Como usar Algolia com Scout

Para a primeira pesquisa de texto completo com o Laravel Scout, você usará o driver Algolia. Algolia é uma plataforma de software como serviço (SaaS) usada para pesquisar grandes quantidades de dados. Ele fornece um painel da Web para os desenvolvedores gerenciarem seus índices de pesquisa e uma API robusta que você pode acessar por meio de um kit de desenvolvimento de software (SDK) em sua linguagem de programação preferida.

Dentro do aplicativo Laravel, você usará o pacote do cliente Algolia para PHP.

Como configurar Algolia

Primeiro, você deve instalar o pacote do cliente de pesquisa Algolia PHP para seu aplicativo.

Execute o comando abaixo.

 composer require algolia/algoliasearch-client-php

Em seguida, você deve definir suas credenciais de Application ID e Secret API Key de Algolia no arquivo .env .

Usando seu navegador da Web, navegue até o painel do Algolia para obter as credenciais de ID do aplicativo e chave secreta da API.

Clique em Configurações na parte inferior da barra lateral esquerda para navegar até a página Configurações .

Em seguida, clique em API Keys na seção Team and Access da página Settings para visualizar as chaves da sua conta Algolia.

Navegando para a página Chaves de API no Algolia Cloud
Página de chaves de API no Algolia Cloud

Na página Chaves de API, observe os valores de ID do aplicativo e Chave de API do administrador . Você usará essas credenciais para autenticar a conexão entre o aplicativo Laravel e o Algolia.

Visualizando o ID do aplicativo e as chaves de API do administrador na página Algolia API Keys
ID do aplicativo e chaves de API do administrador

Adicione o código abaixo ao seu arquivo .env usando seu editor de código e substitua os espaços reservados pelos segredos da API Algolia correspondentes.

 ALGOLIA_APP_ID=APPLICATION_ID ALGOLIA_SECRET=ADMIN_API_KEY

Além disso, substitua a variável SCOUT_DRIVER pelo código abaixo para alterar o valor de meilisearch para algolia . A alteração desse valor instruirá o Scout a usar o driver Algolia.

 SCOUT_DRIVER=algolia

Como criar os controladores de aplicativo

No diretório app/Http/Controllers/ , crie um arquivo TrainSearchController.php para armazenar um controlador para o aplicativo. O controlador listará e adicionará dados ao modelo Train .

Adicione o seguinte bloco de código ao arquivo TrainSearchController.php para construir o 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(); } }

Como Criar as Rotas de Aplicação

Nesta etapa, você criará as rotas para listar e adicionar novos trens ao banco de dados.

Abra seu arquivo routes/web.php e substitua o código existente pelo bloco abaixo.

 <?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');

O código acima define duas rotas na aplicação. A solicitação GET para a rota /trains-lists lista todos os dados de trem armazenados. A solicitação POST para a rota /create-item cria novos dados de treinamento.

Como criar as visualizações do aplicativo

Crie um arquivo dentro do diretório resources/views/ e nomeie-o Train-search.blade.php . O arquivo exibirá a interface do usuário para a funcionalidade de pesquisa.

Adicione o conteúdo do bloco de código abaixo no arquivo Train-search.blade.php para criar uma única página para a funcionalidade de pesquisa.

 <!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>

O código HTML acima contém um elemento de formulário com um campo de entrada e um botão para digitar o título de um trem antes de salvá-lo no banco de dados. O código também possui uma tabela HTML exibindo os detalhes id , title , created_at e updated_at de uma entrada de trem no banco de dados.

Como usar a pesquisa Algolia

Para visualizar a página, navegue até http://127.0.0.1:8000/trains-lists em seu navegador.

Visualizando os dados do modelo de trem exibidos na página de listas de trens
Dados do modelo de treinamento

O banco de dados está vazio no momento, então você precisa inserir um título de um trem de demonstração no campo de entrada e clicar em Criar novo trem para salvá-lo.

Inserindo uma nova entrada de trem
Inserindo uma nova entrada de trem

Para usar o recurso de pesquisa, digite uma palavra-chave de qualquer título de trem salvo no campo de entrada Inserir título para pesquisa e clique em Pesquisar .

Conforme mostrado na imagem abaixo, apenas as entradas de pesquisa que contêm a palavra-chave em seus títulos serão exibidas.

Usando o recurso de pesquisa para encontrar uma entrada de trem
Usando o recurso de pesquisa para encontrar uma entrada de trem

Meilisearch com Laravel Scout

Meilisearch é um mecanismo de pesquisa de código aberto com foco em velocidade, desempenho e experiência aprimorada do desenvolvedor. Ele compartilha vários recursos com o Algolia, usando os mesmos algoritmos, estruturas de dados e pesquisa — mas com uma linguagem de programação diferente.

Os desenvolvedores podem criar e auto-hospedar uma instância Meilisearch em sua infraestrutura local ou na nuvem. A Meilisearch também possui uma oferta de nuvem beta semelhante à Algolia para desenvolvedores que desejam usar o produto sem gerenciar sua infraestrutura.

No tutorial, você já tem uma instância local do Meilisearch em execução em seus contêineres do Docker. Agora você estenderá a funcionalidade Laravel Scout para usar a instância Meilisearch.

Para adicionar o Meilisearch ao aplicativo Laravel, execute o comando abaixo no terminal do seu projeto.

 composer require meilisearch/meilisearch-php

Em seguida, você precisa modificar as variáveis ​​Meilisearch dentro do arquivo .env para configurá-lo.

Substitua as variáveis SCOUT_DRIVER , MEILISEARCH_HOST e MEILISEARCH_KEY no arquivo .env pelas variáveis ​​abaixo.

 SCOUT_DRIVER=meilisearch MEILISEARCH_HOST=http://127.0.0.1:7700 MEILISEARCH_KEY=LockKey

A chave SCOUT_DRIVER especifica o driver que o Scout deve usar, enquanto MEILISEARCH_HOST representa o domínio onde sua instância Meilisearch está rodando. Embora não seja necessário durante o desenvolvimento, é recomendável adicionar a MEILISEARCH_KEY na produção.

Nota: Comente o Algolia ID e Secret ao usar o Meilisearch como seu driver preferido.

Depois de concluir as configurações do .env , você deve indexar seus registros pré-existentes usando o comando Artisan abaixo.

 php artisan scout:import "App\Models\Train"

Laravel Scout com Mecanismo de Banco de Dados

O mecanismo de banco de dados do Scout pode ser mais adequado para aplicativos que usam bancos de dados menores ou gerenciam cargas de trabalho menos intensivas. Atualmente, o mecanismo de banco de dados suporta PostgreSQL e MySQL.

Este mecanismo usa cláusulas “where-like” e índices de texto completo em seu banco de dados existente, permitindo que ele encontre os resultados de pesquisa mais relevantes. Você não precisa indexar seus registros ao usar o mecanismo de banco de dados.

Para usar o mecanismo de banco de dados, você deve definir sua variável SCOUT_DRIVER .env para o banco de dados.

Abra o arquivo .env dentro do aplicativo Laravel e altere o valor da variável SCOUT_DRIVER .

 SCOUT_DRIVER = database

Depois de alterar seu driver para o banco de dados, o Scout passará a usar o mecanismo de banco de dados para pesquisa de texto completo.

Mecanismo de coleta com Laravel Scout

Além do mecanismo de banco de dados, o Scout também oferece um mecanismo de coleta. Este mecanismo usa cláusulas “where” e filtragem de coleta para extrair os resultados de pesquisa mais relevantes.

Ao contrário do mecanismo de banco de dados, o mecanismo de coleção suporta todos os bancos de dados relacionais que o Laravel também suporta.

Você pode usar o mecanismo de coleta definindo a variável de ambiente SCOUT_DRIVER como collection ou especificando manualmente o driver de coleta no arquivo de configuração do Scout.

 SCOUT_DRIVER = collection

Explorador com Elasticsearch

Com a força das consultas do Elasticsearch, o Explorer é um driver moderno do Elasticsearch para o Laravel Scout. Ele oferece um driver Scout compatível e benefícios como armazenamento, pesquisa e análise de grandes quantidades de dados em tempo real. Elasticsearch com Laravel oferece resultados em milissegundos.

Para usar o driver Elasticsearch Explorer em seu aplicativo Laravel, você precisará configurar o arquivo clichê docker-compose.yml que o script Laravel-Scout gerou. Você adicionará as configurações adicionais para o Elasticsearch e reiniciará os contêineres.

Abra seu arquivo docker-compose.yml e substitua seu conteúdo pelo seguinte.

 # 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

Em seguida, execute o comando abaixo para obter a nova imagem do Elasticsearch que você adicionou ao arquivo docker-compose.yml .

 docker-compose up

Em seguida, execute o comando Composer abaixo para instalar o Explorer no projeto.

 composer require jeroen-g/explorer

Você também precisa criar um arquivo de configuração para o driver do Explorer.

Execute o comando Artisan abaixo para gerar um arquivo explorer.config para armazenar as configurações.

 php artisan vendor:publish --tag=explorer.config

O arquivo de configuração gerado acima estará disponível no diretório /config .

Em seu arquivo config/explorer.php , você pode referenciar seu modelo usando a chave indexes .

 'indexes' => [ \App\Models\Train::class ],

Altere o valor da variável SCOUT_DRIVER no arquivo .env para elastic para configurar o Scout para usar o driver do Explorer.

 SCOUT_DRIVER = elastic

Neste ponto, você usará o Explorer dentro do modelo Train implementando a interface do Explorer e substituindo o método mappableAs() .

Abra o arquivo Train.php no diretório App > Models e substitua o código existente pelo código abaixo.

 <?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, ]; } }

Com o código que você adicionou acima, agora você pode usar o Explorer para pesquisar texto no modelo Train .

Laravel + Scout = integração de pesquisa de texto completo rápida, robusta e limpa. Crie um aplicativo de demonstração e experimente-o com este guia ️ Click to Tweet

Resumo

Para desenvolvedores PHP, o Laravel e complementos como o Scout facilitam a integração da funcionalidade de pesquisa de texto completo rápida e robusta. Com o Database Engine, o Collection Engine e os recursos do Meilisearch e do Elasticsearch, você pode interagir com o banco de dados do seu aplicativo e implementar mecanismos avançados de pesquisa em apenas milissegundos.

Gerenciar e atualizar seu banco de dados perfeitamente significa que seus usuários recebem uma experiência ideal enquanto seu código permanece limpo e eficiente.

Com nossas soluções de hospedagem de banco de dados e aplicativos, Kinsta é o seu balcão único para todas as suas necessidades modernas de desenvolvimento Laravel. Os primeiros $ 20 são por nossa conta.