- O Laravel permite implementar desde mecanismos de busca simples com AJAX até buscas avançadas de texto completo usando o Laravel Scout e mecanismos de busca externos como Algolia, Meilisearch ou Elasticsearch.
- Para buscas leves, filtrar no frontend com Alpine.js ou com requisições fetch nativas evita sobrecarregar o servidor e melhora a experiência do usuário em listas pequenas.
- O Laravel Scout centraliza a integração com diferentes mecanismos de busca e facilita a marcação de modelos como pesquisáveis, o gerenciamento de índices e o lançamento uniforme de consultas.
- A escolha do mecanismo de busca (SaaS, código aberto ou banco de dados) deve ser baseada no volume de dados, na complexidade das buscas e nos requisitos de desempenho e manutenção do projeto.
Quando você começa a trabalhar com Laravel e precisa de um mecanismo de busca em tempo real que responde instantaneamenteÉ fácil se perder em meio a mil abordagens possíveis: AJAX com fetch, jQuery, Alpine.js, Scout com Algolia ou Meilisearch, filtragem no frontend, etc. A boa notícia é que o ecossistema Laravel já oferece praticamente tudo o que você precisa para configurar uma busca rápida e eficiente sem se frustrar.
Neste artigo você verá como montar diferentes tipos de pesquisa em tempo real no LaravelDesde o clássico recurso de autocompletar com AJAX até buscas de texto completo com o Laravel Scout e mecanismos de busca como Algolia, Meilisearch, o próprio banco de dados ou até mesmo o Elasticsearch. Você também encontrará alternativas leves com o Alpine.js para filtrar dados diretamente no navegador quando o volume de dados for pequeno.
O que é uma busca em tempo real no Laravel e como funciona basicamente?
A ideia por trás de uma busca em tempo real é que, enquanto o usuário digita em um campo de textoUma consulta é acionada e os resultados são atualizados sem recarregar a página. Tecnicamente, isso envolve três componentes principais: o backend Laravel, o JavaScript do navegador e a troca de dados em formato JSON.
Por um lado, O Laravel atua como camada de servidor. É responsável por receber solicitações, interpretar os parâmetros de busca (o texto inserido), consultar o banco de dados e retornar uma resposta estruturada, geralmente em formato JSON. Essa resposta pode indicar sucesso, erro ou que nenhum resultado foi encontrado.
Na outra ponta, O JavaScript é responsável por ouvir os eventos do usuário. No campo de pesquisa, envie solicitações assíncronas (AJAX) para o servidor e exiba os dados retornados na página sem que o navegador precise atualizar a página completamente. Isso pode ser feito com a função nativa `fetch`, jQuery AJAX ou pequenas bibliotecas reativas como Alpine.js.
Com esse mecanismo básico, você pode construir a partir de um Preenchimento automático simples com alguns registros, até um mecanismo de busca de texto completo avançado com relevância, paginação e filtros, suportado por bibliotecas como o Laravel Scout e mecanismos de busca externos otimizados para pesquisa.
Modelo, rotas e controlador para um mecanismo de busca básico em tempo real.
Antes de começar a usar JavaScript, você precisa garantir que o lado do Laravel esteja bem organizado: Um modelo Eloquent para pesquisa, rotas claras e um controlador dedicado. para gerenciar a lógica de busca em tempo real.
O primeiro passo é ter um modelo Eloquent que represente a tabela onde você vai pesquisar. Imagine uma tabela de países e um modelo chamado País Muito simples, sem registros de data e hora e com atribuição em massa permitida:
Exemplo de um modelo Eloquent mínimo para buscas:
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Pais extends Model
{
use HasFactory;
protected $guarded = [];
public $timestamps = false;
}
Indica-se aqui que o modelo Pais está localizado no namespace padrão do Laravel.Ela herda de `Model` e permite atribuir valores a qualquer campo com `create()` deixando o array protegido vazio. Ao desabilitar os timestamps com `public $timestamps = false`, você evita problemas caso a tabela não possua as colunas `created_at` e `updated_at`.
O próximo passo é definir as rotas que irão lidar tanto com a exibição no mecanismo de busca quanto com as requisições AJAXUm esquema muito comum combina uma rota GET para exibir a visualização e uma rota POST projetada para receber consultas em tempo real:
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\BuscadorController;
Route::get('/', function () {
return view('welcome');
});
Route::get('buscador', [BuscadorController::class, 'index']);
Route::post('buscador', [BuscadorController::class, 'buscar']);
A rota raiz retorna uma tela de boas-vindas, enquanto a URL /search é reservado para a funcionalidade de pesquisaO método index() do controlador exibe o formulário e o campo de pesquisa, enquanto o método search() processa as solicitações assíncronas enviadas pelo navegador.
No controlador, você pode implementar um padrão muito prático: Prepare uma matriz de resposta padrão para o caso de erro. e só a sobrescreva quando for de fato uma solicitação AJAX válida e a consulta for executada sem problemas.
O controlador pode ter um estrutura semelhante a isto:
namespace App\Http\Controllers;
use App\Models\Pais;
use Illuminate\Http\Request;
class BuscadorController extends Controller
{
public function index()
{
return view('welcome');
}
public function buscar(Request $request)
{
$response = [
'success' => false,
'message' => 'Hubo un error',
];
if ($request->ajax()) {
$data = Pais::where('nombre', 'like', $request->texto.'%')
->take(10)
->get();
$response = [
'success' => true,
'message' => 'Consulta correcta',
'data' => $data,
];
}
return response()->json($response);
}
}
Neste ponto você já tem O ciclo completo do backend: requisição AJAX recebida, verificação de que se trata de uma requisição AJAX, consulta com `where like` e limitação dos resultados. para um número razoável usando take(10) para evitar sobrecarregar o banco de dados. A resposta é sempre enviada em JSON, o que simplifica bastante o trabalho do frontend.
Blade view e JavaScript fetch para pesquisa reativa
Com o modelo, as rotas e o controlador prontos, é hora de construir a parte visível: Um formulário com um campo de pesquisa e um bloco para exibir os resultados., além do JavaScript responsável por fazer as requisições em segundo plano.
A visualização Blade pode ser muito simples, baseando-se em Token CSRF que o Laravel injeta para validar solicitações POST e em um campo de pesquisa que é conveniente de usar:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<strong><meta name="csrf-token" content="{{ csrf_token() }}"></strong>
<title>Laravel</title>
</head>
<body>
<form action="" method="post">
<input type="search" name="texto" id="buscar">
</form>
<div id="resultado"></div>
<script>
window.addEventListener('load', function () {
const buscar = document.getElementById('buscar');
const resultado = document.getElementById('resultado');
buscar.addEventListener('keyup', function () {
fetch('/buscador', {
method: 'post',
body: JSON.stringify({ texto: buscar.value }),
headers: {
'Content-Type': 'application/json',
'X-Requested-With': 'XMLHttpRequest',
'X-CSRF-Token': document.head.querySelector('[name~="csrf-token"][content]').content,
},
})
.then(response => response.json())
.then(data => {
let html = '';
if (data.success) {
html += '<ul>';
for (let i in data.data) {
html += '<li>' + data.data[i].nombre + '</li>';
}
html += '<ul>';
} else {
html += 'No existen resultados';
}
resultado.innerHTML = html;
});
});
});
</script>
</body>
</html>
Neste exemplo, o script Aguarde o evento keyup no campo de entrada de pesquisa.Cada tecla pressionada aciona uma requisição fetch para o caminho /search. O texto atual do campo é enviado em formato JSON, e cabeçalhos importantes como X-Requested-With são incluídos para indicar que se trata de uma requisição AJAX, juntamente com o token CSRF para contornar a proteção nativa do Laravel.
Quando a resposta chega, ela é transformada em JSON e gerada dinamicamente. uma pequena lista HTML com os resultadosou uma mensagem como "Nenhum resultado encontrado" quando a consulta não retorna dados. Tudo isso sem recarregar a página, de forma natural para o usuário.
Esse padrão pode ser ainda mais refinado com pequenos detalhes de UX, como adicionar um atraso (debounce) Entre as teclas pressionadas, exiba um indicador de carregamento ou trate erros de rede para evitar que a interface pareça congelada quando algo falhar.
Pesquisa em tempo real com Laravel e AJAX usando jQuery
Embora o jogo "fetch" tenha ganhado muita popularidade atualmente, jQuery AJAX continua sendo muito popular. Em projetos legados ou em equipes que já o implementaram, a ideia é exatamente a mesma: capturar o que o usuário digita, fazer uma solicitação assíncrona e atualizar o DOM.
Um fluxo de trabalho típico com jQuery em Laravel para pesquisa em tempo real geralmente inclui estas etapas básicas: Defina uma rota específica, crie um controlador dedicado e construa a visualização Blade com o campo de entrada de pesquisa. E, por fim, adicione o código jQuery que aciona o AJAX conforme é digitado.
O processo funciona assim: quando o usuário começa a digitar, jQuery envia uma consulta ao servidor. com a string de pesquisa. O Laravel filtra as informações no banco de dados, retorna um JSON com os resultados correspondentes e o jQuery atualiza um contêiner HTML na página para refletir as correspondências, tudo em questão de milissegundos.
A vantagem de usar jQuery é que Isso resume bem a sintaxe do AJAX. E é muito fácil de ler se você já tiver a biblioteca no seu projeto. No entanto, você estará adicionando uma dependência extra que pode não ser necessária se você puder trabalhar com JavaScript moderno e o fetch nativo.
Filtragem e busca em tempo real no frontend com Alpine.js
Quando os dados a serem exibidos são relativamente pequenos (por exemplo, menos de 50 itens), nem sempre vale a pena configurar um backend com pesquisas complexas. Nesses casos, uma opção muito conveniente é Filtre diretamente no navegador com Alpine.js, sem fazer requisições ao servidor enquanto o usuário digita.
A ideia é pré-calcular uma string de busca para cada elemento (por exemplo, nome, descrição e categoria em letras minúsculas), armazená-la em um atributo data-search-text e deixar que o Alpine.js cuide do resto. Mostrar ou ocultar elementos de acordo com o texto escrito. em um campo de pesquisa.
O componente Alpine.js pode ter uma estrutura semelhante a esta: filtrarItens
{
search: '',
hasResults: true,
selectedValue: '',
init() {
this.$watch('search', () => this.filterItems());
this.$nextTick(() => this.$refs.searchInput?.focus());
},
filterItems() {
const searchLower = this.search.toLowerCase().trim();
const cards = this.$el.querySelectorAll('.item-card');
let visibleCount = 0;
cards.forEach(card => {
const text = card.dataset.searchText || '';
const isVisible = searchLower === '' || text.includes(searchLower);
card.style.display = isVisible ? '' : 'none';
if (isVisible) visibleCount++;
});
this.hasResults = visibleCount > 0;
},
}
Na visualização, cada cartão ou linha de dados teria um atributo. texto de pesquisa de dados com o texto já preparado em letras minúsculasPortanto, o filtro é reduzido a uma função includes() em JavaScript, que é muito rápida para listas curtas:
<input type="search" x-model="search" x-ref="searchInput" placeholder="Buscar..." />
<div>
<div class="item-card" data-search-text="formulario contacto simple">
<h3>Formulario de contacto</h3>
<p>Formulario de contacto simple</p>
</div>
</div>
Além disso, você pode exibir um bloco de estado vazio somente quando Não foram encontrados resultados para o termo de pesquisa atual.convidando o usuário a modificar o texto ou limpar o campo com um botão que simplesmente redefine a pesquisa para uma string vazia.
Essa abordagem apresenta vantagens claras: Não há chamadas ao servidor durante a pesquisa.A interação é praticamente instantânea, e a lógica permanece altamente local e fácil de depurar. É perfeita para seletores rápidos, modais de seleção de itens ou pequenos catálogos incorporados em uma página Laravel.
Laravel Scout: Busca de texto completo com mecanismos especializados
Quando as coisas ficam sérias e você precisa buscas de texto completo rápidas, relevantes e escaláveisO caminho natural no Laravel é o Laravel Scout. O Scout é uma camada de integração que permite conectar facilmente seus modelos Eloquent com mecanismos de busca como Algolia, Meilisearch, seu próprio banco de dados, coleções em memória ou até mesmo o Elasticsearch por meio de controladores externos.
Para começar a usar o Scout, o procedimento usual é Crie um novo projeto Laravel ou reutilize um já existente.Para executá-lo, use o Docker (por exemplo, com o Laravel Sail) e instale a biblioteca com o Composer. Feito isso, publique o arquivo de configuração scout.php e ajuste as variáveis de ambiente de acordo com o driver que deseja usar.
Um fluxo de trabalho típico seria instalar o Scout com o Composer, publicar sua configuração e Ative a fila de indexação com SCOUT_QUEUE=true No arquivo .env, certifique-se de que as operações que consomem muitos recursos sejam processadas em segundo plano, melhorando os tempos de resposta do aplicativo. Além disso, você deve garantir que a variável de ambiente DB_HOST aponte para o banco de dados que você está usando, o que é especialmente importante se você estiver usando contêineres Docker.
Para que um modelo participe das buscas dos Escoteiros, é necessário Para marcar explicitamente um item como pesquisável, adicione a característica Searchable.Por exemplo, se você tiver um modelo de Trem que representa uma tabela de trens com um campo de título, você poderia defini-lo assim:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Searchable;
class Train extends Model
{
use Searchable;
protected $fillable = ['title'];
public function searchableAs()
{
return 'trains_index';
}
}
O método searchableAs permite Personalize o nome do índice no mecanismo de busca.Em vez de usar o nome padrão derivado do modelo, o Scout assume o controle. A partir daí, o Scout gerencia a sincronização das operações de criação, atualização e exclusão com o índice remoto ou local, dependendo do driver escolhido.
Laravel Scout com Algolia: Busca SaaS ultrarrápida
Algolia é um serviço SaaS focado em para oferecer buscas muito rápidas e relevantes em grandes volumes de dados.Possui um painel web para gerenciar índices, regras de relevância, sinônimos, etc., e se integra muito bem com o Laravel através do Scout e do cliente PHP oficial.
Para usar o Algolia com o Scout, você precisará instalar o cliente PHP com o Composer, registrar suas credenciais no arquivo .env (ID do aplicativo e chave da API de administrador) e definir SCOUT_DRIVER=algólia Para instruir o Scout a usar este mecanismo. No painel do Algolia, você pode obter tanto o ID do aplicativo quanto a chave administrativa.
Após configurar o ambiente, você pode usar métodos como: Train::search('text')->paginate(6) diretamente em seus controladores para realizar buscas nos campos indexados, recebendo resultados em formato Eloquent paginado, prontos para serem passados para uma view Blade.
Por exemploVocê poderia ter um controle índice que lista todos os trens ou realiza uma busca se um parâmetro de pesquisa de título for recebido, e um método de criação para inserir novos trens no índice:
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'));
}
public function create(Request $request)
{
$this->validate($request, ['title' => 'required']);
Train::create($request->all());
return back();
}
Na vista correspondente, você pode combinar um formulário para registrar novos trens e outro formulário GET com um campo de pesquisa de título que aciona a busca ao ser enviado. Em seguida, basta iterar pela coleção de trens e exibir seus campos em uma tabela, aproveitando os links de paginação gerados pelo Laravel.
Explorador com Meilisearch, banco de dados e coleções
Se preferir evitar serviços externos, Meilisearch é um mecanismo de busca de código aberto. que você pode implantar localmente ou em sua infraestrutura. O Scout se integra ao Meilisearch de maneira muito semelhante ao Algolia, simplesmente alterando o driver e adicionando as variáveis MEILISEARCH_HOST e MEILISEARCH_KEY ao arquivo .env.
Para utilizá-lo, você instala o cliente PHP Meilisearch e ajusta as configurações. SCOUT_DRIVER=meilisearch e aponte MEILISEARCH_HOST para o URL da instância (por exemplo, http://127.0.0.1:7700). Se você já tiver registros anteriores, poderá indexá-los com o comando php artisan scout:import "App\Models\Train" para que o mecanismo os tenha disponíveis.
Em aplicações de menor ou médio porte, você também pode escolher a opção Banco de dados de motoristas ScoutIsso aproveita os índices de texto completo e os comandos LIKE do seu banco de dados MySQL ou PostgreSQL. Nesse caso, você não precisa de um serviço externo; basta definir SCOUT_DRIVER=database para que o Scout use o próprio banco de dados como mecanismo de busca.
Outra opção interessante é o Coleção de drivers, que funciona com coleções Eloquent na memória.Este mecanismo filtra resultados usando cláusulas WHERE e filtragem de coleções, sendo compatível com qualquer banco de dados suportado pelo Laravel. Você pode ativá-lo com `SCOUT_DRIVER=collection` ou ajustando o arquivo de configuração do Scout para configurações mais específicas.
Integração com o Elasticsearch usando o Explorer
Se suas necessidades de pesquisa envolverem Trabalhar com grandes volumes de dados e realizar análises em tempo real.O Elasticsearch é um clássico. No ecossistema Laravel, uma forma moderna de integrá-lo ao Scout é usar o controlador Explorer, que atua como uma ponte entre seus modelos e um cluster Elasticsearch.
Para isso, geralmente utiliza-se o Docker, juntamente com um arquivo docker-compose robusto que, além dos serviços típicos (Laravel, MySQL, Redis, Meilisearch, etc.), Contêineres Elasticsearch e KibanaEm seguida, instale o pacote jeroen-g/explorer via Composer e publique seu arquivo de configuração para indicar quais modelos devem ser indexados.
No arquivo config/explorer.php, você pode registrar seus modelos sob a chave indexes, por exemplo, adicionando App\Models\Train::classAlém disso, você deve alterar o driver do Scout para elastic no arquivo .env com SCOUT_DRIVER=elastic para que tudo aponte para o Elasticsearch.
No modelo Train, a interface Explored deve ser implementada e o método sobrescrito. mapeávelComoque define o mapa de campos que serão enviados para o índice. Um exemplo mínimo seria:
use JeroenG\Explorer\Application\Explored;
use Laravel\Scout\Searchable;
class Train extends Model implements Explored
{
use Searchable;
protected $fillable = ['title'];
public function mappableAs(): array
{
return [
'id' => $this->id,
'title' => $this->title,
];
}
}
A partir daqui, Você pode iniciar pesquisas no Elasticsearch usando a mesma interface do Scout., beneficiando-se de tempos de resposta muito baixos e de todo o poder de consulta deste mecanismo, mas sem sair do ecossistema Laravel.
Com todas essas abordagens — desde o preenchimento automático básico com fetch ou jQuery, até a filtragem no frontend com Alpine.js, passando por buscas de texto completo com Laravel Scout e vários drivers — O Laravel oferece uma ampla gama de opções para implementar buscas em tempo real. Adaptado ao tamanho do seu projeto, ao desempenho que você precisa e à infraestrutura que você está disposto a manter.
Tabela de conteúdos
- O que é uma busca em tempo real no Laravel e como funciona basicamente?
- Modelo, rotas e controlador para um mecanismo de busca básico em tempo real.
- Blade view e JavaScript fetch para pesquisa reativa
- Pesquisa em tempo real com Laravel e AJAX usando jQuery
- Filtragem e busca em tempo real no frontend com Alpine.js
- Laravel Scout: Busca de texto completo com mecanismos especializados
- Laravel Scout com Algolia: Busca SaaS ultrarrápida
- Explorador com Meilisearch, banco de dados e coleções
- Integração com o Elasticsearch usando o Explorer