Guida completa alla ricerca in tempo reale in Laravel

Ultimo aggiornamento: Dicembre 5 2025
  • Laravel consente di implementare di tutto, dai semplici motori di ricerca con AJAX alle ricerche avanzate full-text utilizzando Laravel Scout e motori di ricerca esterni come Algolia, Meilisearch o Elasticsearch.
  • Per ricerche leggere, il filtraggio sul frontend con Alpine.js o con richieste di recupero native evita di sovraccaricare il server e migliora l'esperienza utente in elenchi di piccole dimensioni.
  • Laravel Scout centralizza l'integrazione con diversi motori di ricerca e semplifica la marcatura dei modelli come ricercabili, la gestione degli indici e l'avvio di query in modo uniforme.
  • La scelta del motore (SaaS, open source o database) dovrebbe basarsi sul volume dei dati, sulla complessità delle ricerche e sui requisiti di prestazioni e manutenzione del progetto.

ricerca in tempo reale in Laravel

Quando inizi a lavorare con Laravel e hai bisogno di un motore di ricerca in tempo reale che risponde istantaneamenteÈ facile perdersi tra mille possibili approcci: AJAX con fetch, jQuery, Alpine.js, Scout con Algolia o Meilisearch, filtraggio frontend, ecc. La buona notizia è che l'ecosistema Laravel fornisce già praticamente tutto il necessario per impostare una ricerca fluida e veloce senza fallire nel tentativo.

In questo articolo vedrai come assemblare diversi tipi di ricerca in tempo reale in LaravelDal classico completamento automatico AJAX alle ricerche full-text con Laravel Scout e motori di ricerca come Algolia, Meilisearch, il database stesso o persino Elasticsearch. Troverete anche alternative leggere con Alpine.js per filtrare i dati direttamente nel browser quando il volume di dati è ridotto.

Cos'è una ricerca in tempo reale in Laravel e come funziona?

L'idea alla base di una ricerca in tempo reale è che, mentre l'utente digita in un campo di testoViene attivata una query e i risultati vengono aggiornati senza ricaricare la pagina. Tecnicamente, questo coinvolge tre componenti chiave: il backend Laravel, il codice JavaScript del browser e lo scambio di dati in formato JSON.

Da un lato, Laravel funge da livello server È responsabile della ricezione delle richieste, dell'interpretazione dei parametri di ricerca (il testo inserito), dell'interrogazione del database e della restituzione di una risposta strutturata, solitamente in formato JSON. Questa risposta può indicare un esito positivo, un errore o l'assenza di risultati.

D'altra parte, JavaScript è responsabile dell'ascolto degli eventi utente. Nell'input di ricerca, invia richieste asincrone (AJAX) al backend e visualizza i dati restituiti sulla pagina senza che il browser esegua un aggiornamento completo. Questo può essere fatto con il fetch nativo, jQuery AJAX o piccole librerie reattive come Alpine.js.

Con questo meccanismo di base puoi costruire da un Completamento automatico semplice con pochi record, fino a un motore di ricerca full-text avanzato con pertinenza, impaginazione e filtri, supportato da librerie come Laravel Scout e motori di ricerca esterni ottimizzati per la ricerca.

Modello, percorsi e controller per un motore di ricerca di base in tempo reale

Prima di addentrarti in JavaScript, devi assicurarti che il lato Laravel sia ben organizzato: un modello Eloquent per la ricerca, percorsi chiari e un controller dedicato per gestire la logica di ricerca in tempo reale.

Il primo passo è avere un modello Eloquent che rappresenti la tabella in cui si desidera effettuare la ricerca. Immagina una tabella di paesi e un modello chiamato Genitori Molto semplice, senza timestamp e con assegnazione in blocco consentita:

Esempio di un modello Eloquent minimo per le ricerche:

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;
}

Si indica qui che il modello Pais si trova nello spazio dei nomi standard di LaravelEredita da Model e consente di assegnare qualsiasi campo con create() lasciando vuoto l'array protetto. Disabilitando i timestamp con public $timestamps = false, si evitano problemi se la tabella non contiene le colonne created_at e updated_at.

Il passo successivo è definire i percorsi che gestiranno sia la visualizzazione del motore di ricerca che le richieste AJAXUno schema molto comune combina un percorso GET per visualizzare la vista e un percorso POST progettato per ricevere query in tempo reale:

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

Il percorso radice restituisce una vista di benvenuto, mentre l'URL /search è riservato alla funzionalità di ricercaIl metodo index() del controller visualizza il modulo e l'input di ricerca, mentre il metodo search() elabora le richieste asincrone inviate dal browser.

Nel controller è possibile implementare uno schema molto pratico: Preparare un array di risposta predefinito in caso di errore e sovrascriverla solo quando si tratta effettivamente di una richiesta AJAX valida e la query viene eseguita senza problemi.

Il controller potrebbe avere un struttura simile Questo:

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);
}
}

A questo punto hai già il ciclo completo del backend: richiesta AJAX in arrivo, verifica che sia AJAX, query con where like e limitazione dei risultati a un numero ragionevole usando take(10) per evitare di sovraccaricare il database. La risposta viene sempre inviata in JSON, il che semplifica notevolmente il lavoro del frontend.

Visualizzazione della lama e recupero JavaScript per la ricerca reattiva

Con il modello, i percorsi e il controller pronti, è il momento di costruire la parte visibile: un modulo con un campo di ricerca e un blocco per visualizzare i risultati, più il codice JavaScript responsabile dell'esecuzione delle richieste in background.

La vista Blade può essere molto semplice, basandosi su Token CSRF che Laravel inietta per convalidare le richieste POST e in un input di ricerca comodo da usare:

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

In questo esempio lo script Ascolta l'evento keyup sull'input di ricercaOgni pressione di un tasto attiva una richiesta di recupero al percorso /search. Il testo corrente del campo viene inviato in formato JSON e vengono incluse intestazioni chiave come X-Requested-With per indicare che si tratta di AJAX, insieme al token CSRF per bypassare la protezione nativa di Laravel.

Quando arriva la risposta, questa viene trasformata in JSON e generata dinamicamente. un piccolo elenco HTML con i risultatio un messaggio come "Nessun risultato trovato" quando la query non restituisce alcun dato. Tutto questo senza ricaricare la pagina, in modo naturale per l'utente.

Questo modello può essere ulteriormente perfezionato con piccoli dettagli UX, come l'aggiunta di un ritardo (antirimbalzo) tra una pressione dei tasti e l'altra, visualizzare un caricatore o gestire gli errori di rete per evitare che l'interfaccia sembri bloccata quando si verifica un errore.

Ricerca live con Laravel e AJAX utilizzando jQuery

Sebbene il riporto abbia guadagnato molto terreno al giorno d'oggi, jQuery AJAX rimane molto popolare Nei progetti legacy o nei team che lo hanno già implementato. L'idea è esattamente la stessa: catturare ciò che l'utente digita, effettuare una richiesta asincrona e aggiornare il DOM.

Un tipico flusso di lavoro con jQuery in Laravel per la ricerca live solitamente include questi passaggi di base: definire un percorso specifico, creare un controller dedicato, costruire la vista Blade con l'input di ricerca Infine, aggiungi il codice jQuery che attiva AJAX mentre viene digitato.

Il processo funziona così: quando l'utente inizia a digitare, jQuery invia una query al server con la stringa di ricerca. Laravel filtra le informazioni nel database, restituisce un file JSON con i risultati corrispondenti e jQuery aggiorna un contenitore HTML sulla pagina per riflettere le corrispondenze, il tutto in pochi millisecondi.

Il vantaggio di usare jQuery è che Riassume abbastanza bene la sintassi di AJAX Ed è molto semplice da leggere se hai già la libreria nel tuo progetto. Tuttavia, stai aggiungendo una dipendenza extra che potrebbe non essere necessaria se puoi lavorare con JavaScript moderno e fetch nativo.

Filtraggio e ricerca in tempo reale sul frontend con Alpine.js

Quando i dati da visualizzare sono relativamente piccoli (ad esempio, meno di 50 articoli), non sempre vale la pena impostare un backend con ricerche complesse. In questi casi, un'opzione molto comoda è Filtra direttamente nel browser con Alpine.js, senza effettuare richieste al server mentre l'utente digita.

L'idea è di precalcolare una stringa di ricerca per ogni elemento (ad esempio, nome, descrizione e categoria in minuscolo), memorizzarla in un attributo data-search-text e lasciare che Alpine.js gestisca il resto. mostrare o nascondere elementi in base al testo scritto in un campo di ricerca.

Il componente Alpine.js può avere una struttura simile a questa: elementi filtro

{
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;
},
}

Nella vista, ogni scheda o riga di dati avrebbe un attributo data-search-text con il testo già preparato in minuscoloPertanto, il filtro si riduce a una funzione includes() in JavaScript, che è molto veloce per elenchi brevi:

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

Inoltre, è possibile visualizzare un blocco di stato vuoto solo quando Non ci sono risultati per il termine di ricerca corrente.invitando l'utente a modificare il testo o a cancellare il campo con un pulsante che semplicemente reimposta la ricerca su una stringa vuota.

Questo approccio presenta chiari vantaggi: Durante la ricerca non vengono effettuate chiamate al server.L'interazione è praticamente istantanea e la logica rimane altamente locale e facile da debuggare. È perfetto per selettori rapidi, finestre modali di selezione di elementi o piccoli cataloghi incorporati in una pagina Laravel.

Laravel Scout: ricerca full-text con motori specializzati

Quando le cose si fanno serie e hai bisogno ricerche full-text veloci, pertinenti e scalabiliIl percorso naturale in Laravel è Laravel Scout. Scout è un livello di integrazione che consente di connettere facilmente i modelli Eloquent con motori di ricerca come Algolia, Meilisearch, il proprio database, collezioni in-memory o persino Elasticsearch tramite controller esterni.

Per iniziare con Scout, la cosa normale è crea un nuovo progetto Laravel o riutilizza uno esistentePer avviarlo, usa Docker (ad esempio, con Laravel Sail) e poi installa la libreria con Composer. Una volta fatto, pubblica il file di configurazione scout.php e modifica le variabili d'ambiente in base al driver che desideri utilizzare.

Un flusso di lavoro tipico sarebbe quello di installare Scout con Composer, pubblicare la sua configurazione e attiva la coda di indicizzazione con SCOUT_QUEUE=true Nel file .env, assicurati che le operazioni che richiedono molte risorse vengano elaborate in background, migliorando i tempi di risposta dell'applicazione. Inoltre, devi assicurarti che DB_HOST punti al database in uso, il che è particolarmente importante se utilizzi container Docker.

Affinché un modello possa partecipare alle ricerche Scout, è necessario Per contrassegnarlo esplicitamente come ricercabile aggiungendo la caratteristica RicercabileAd esempio, se si dispone di un modello Train che rappresenta una tabella di treni con un campo titolo, è possibile definirlo in questo modo:

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';
}
}

Il metodo searchableAs consente personalizzare il nome dell'indice nel motore di ricercaInvece di utilizzare il nome predefinito derivato dal modello, Scout prende il sopravvento. Da qui, Scout gestisce la sincronizzazione delle operazioni di creazione, aggiornamento ed eliminazione con l'indice remoto o locale, a seconda del driver scelto.

Laravel Scout con Algolia: ricerca SaaS velocissima

Algolia è un servizio SaaS focalizzato su per offrire ricerche molto veloci e pertinenti su grandi volumi di datiDispone di un pannello web per la gestione di indici, regole di pertinenza, sinonimi, ecc. e si integra molto bene con Laravel tramite Scout e il client PHP ufficiale.

Per utilizzare Algolia con Scout, dovrai installare il suo client PHP con Composer, registrare le tue credenziali nel file .env (ID applicazione e chiave API di amministrazione) e imposta SCOUT_DRIVER=algolia per dire a Scout di utilizzare questo motore. Dal pannello Algolia è possibile ottenere sia l'ID dell'applicazione che la chiave amministrativa.

Una volta configurato l'ambiente, è possibile utilizzare metodi come Train::search('testo')->paginate(6) direttamente nei controller per eseguire ricerche sui campi indicizzati, ricevendo i risultati in formato Eloquent impaginato, pronti per essere passati a una vista Blade.

Ad esPotresti avere un controller Index che elenca tutti i treni o esegue una ricerca se viene ricevuto un parametro titlesearch e un metodo create per inserire nuovi treni nell'indice:

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();
}

Nella vista corrispondente, puoi combinare un modulo per la registrazione di nuovi treni e un altro modulo GET con un campo titlesearch che attiva la ricerca al momento dell'invio. A questo punto, è sufficiente scorrere la raccolta di treni e visualizzare i relativi campi in una tabella, sfruttando i link di paginazione generati da Laravel.

Esplora con Meilisearch, database e collezioni

Se preferisci evitare i servizi esterni, Meilisearch è un motore di ricerca open source che puoi implementare localmente o sulla tua infrastruttura. Scout si integra con Meilisearch in modo molto simile ad Algolia, semplicemente modificando il driver e aggiungendo le variabili MEILISEARCH_HOST e MEILISEARCH_KEY al file .env.

Per utilizzarlo, installa il client PHP Meilisearch, regola SCOUT_DRIVER=meilisearch e punta MEILISEARCH_HOST all'URL dell'istanza (ad esempio, http://127.0.0.1:7700). Se avevi già dei record precedenti, puoi indicizzarli con il comando php artisan scout:import "App\Models\Train" in modo che il motore li abbia a disposizione.

Nelle applicazioni più piccole o moderate, puoi anche scegliere Database dei conducenti ScoutQuesto sfrutta gli indici full-text e i comandi LIKE sul tuo database MySQL o PostgreSQL. In questo caso, non hai bisogno di un servizio esterno; è sufficiente impostare SCOUT_DRIVER=database affinché Scout utilizzi il database stesso come motore di ricerca.

Un'altra opzione interessante è il file raccolta di driver, che funziona sulle raccolte Eloquent in memoriaQuesto motore filtra i risultati utilizzando clausole WHERE e filtri di raccolta ed è compatibile con qualsiasi database supportato da Laravel. È possibile attivarlo con `SCOUT_DRIVER=collection` o modificando il file di configurazione di Scout per impostazioni più specifiche.

Integrazione con Elasticsearch tramite Explorer

Se la tua ricerca ha bisogno di coinvolgere lavorare con enormi volumi di dati e analisi in tempo realeElasticsearch è un classico. Nell'ecosistema Laravel, un modo moderno per integrarlo con Scout è utilizzare il controller Explorer, che funge da ponte tra i modelli e un cluster Elasticsearch.

Per fare questo, di solito si usa Docker, insieme a un ricco file docker-compose che, oltre ai servizi tipici (Laravel, MySQL, Redis, Meilisearch, ecc.), Contenitori Elasticsearch e KibanaQuindi si installa il pacchetto jeroen-g/explorer tramite Composer e si pubblica il suo file di configurazione per indicare quali modelli devono essere indicizzati.

Nel file config/explorer.php puoi registrare i tuoi modelli sotto la chiave indexes, ad esempio aggiungendo App\Modelli\Train::classInoltre, modifica il driver Scout in elastic nel file .env con SCOUT_DRIVER=elastic in modo che tutto punti a Elasticsearch.

All'interno del modello Train, l'interfaccia Explored deve essere implementata e il metodo sovrascritto. mappabileComeche definisce la mappa dei campi che verranno inviati all'indice. Un esempio minimo sarebbe:

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

Da ora in poi, È possibile avviare ricerche su Elasticsearch utilizzando la stessa interfaccia Scout., beneficiando di tempi di risposta molto bassi e della piena potenza di query di questo motore, ma senza uscire dall'ecosistema Laravel.

Con tutti questi approcci, dal completamento automatico di base con fetch o jQuery, al filtraggio frontend con Alpine.js, alle ricerche full-text con Laravel Scout e vari driver, Laravel ti offre una vasta gamma di opzioni per implementare ricerche in tempo reale su misura in base alle dimensioni del tuo progetto, alle prestazioni di cui hai bisogno e all'infrastruttura che sei disposto a mantenere.

  Programmazione di videogiochi: come iniziare - Guida passo passo