- Met Laravel kunt u alles implementeren, van eenvoudige zoekmachines met AJAX tot geavanceerde zoekopdrachten in volledige tekst met Laravel Scout en externe zoekmachines zoals Algolia, Meilisearch of Elasticsearch.
- Bij lichte zoekopdrachten voorkomt het filteren op de frontend met Alpine.js of met native fetch requests dat de server overbelast raakt en verbetert de gebruikerservaring bij kleine lijsten.
- Laravel Scout centraliseert de integratie met verschillende zoekmachines en maakt het eenvoudig om modellen als doorzoekbaar te markeren, indexen te beheren en query's op uniforme wijze te starten.
- De keuze van de engine (SaaS, open source of database) moet gebaseerd zijn op de hoeveelheid data, de complexiteit van de zoekopdrachten en de prestatie- en onderhoudsvereisten van het project.
Wanneer je met Laravel aan de slag gaat en een realtime zoekmachine die direct reageertHet is makkelijk om te verdwalen in duizend mogelijke benaderingen: AJAX met fetch, jQuery, Alpine.js, Scout met Algolia of Meilisearch, frontend-filtering, enzovoort. Het goede nieuws is dat het Laravel-ecosysteem al vrijwel alles biedt wat je nodig hebt om een soepele en snelle zoekopdracht op te zetten zonder dat je daarbij vastloopt.
In dit artikel leest u hoe u het in elkaar zet verschillende soorten realtime zoeken in LaravelVan klassieke AJAX-autocomplete tot full-text zoekopdrachten met Laravel Scout en zoekmachines zoals Algolia, Meilisearch, de database zelf of zelfs Elasticsearch. Je ziet ook lichtgewicht alternatieven met Alpine.js om gegevens direct in de browser te filteren wanneer het datavolume klein is.
Wat is een realtime zoekopdracht in Laravel en hoe werkt het in de basis?
Het idee achter een realtime zoekopdracht is dat, terwijl de gebruiker in een tekstveld typtEr wordt een query geactiveerd en de resultaten worden bijgewerkt zonder de pagina opnieuw te laden. Technisch gezien omvat dit drie belangrijke componenten: de Laravel-backend, de JavaScript van de browser en de uitwisseling van gegevens in JSON-formaat.
Enerzijds Laravel fungeert als serverlaag Het is verantwoordelijk voor het ontvangen van verzoeken, het interpreteren van zoekparameters (de ingevoerde tekst), het raadplegen van de database en het retourneren van een gestructureerd antwoord, meestal in JSON-formaat. Dit antwoord kan een succes, een fout of een foutmelding aangeven, of aangeven dat er geen resultaten zijn gevonden.
Aan het andere einde, JavaScript is verantwoordelijk voor het luisteren naar gebruikersgebeurtenissen. Stuur bij de zoekopdracht asynchrone verzoeken (AJAX) naar de backend en toon de geretourneerde gegevens op de pagina zonder dat de browser een volledige verversing uitvoert. Dit kan met native fetch, jQuery AJAX of kleine reactieve bibliotheken zoals Alpine.js.
Met dit basismechanisme kun je bouwen vanaf een Eenvoudige autocomplete met een paar records, tot een geavanceerde full-text zoekmachine met relevantie, paginering en filters, ondersteund door bibliotheken zoals Laravel Scout en externe zoekmachines die geoptimaliseerd zijn voor zoeken.
Model, routes en controller voor een eenvoudige realtime zoekmachine
Voordat je je verdiept in JavaScript, moet je ervoor zorgen dat de Laravel-kant goed georganiseerd is: een welsprekend model om op te zoeken, duidelijke routes en een toegewijde controller om de zoeklogica in realtime te beheren.
De eerste stap is het hebben van een Eloquent-model dat de tabel vertegenwoordigt waarin u gaat zoeken. Stel u een tabel met landen voor en een model genaamd Land Heel eenvoudig, zonder tijdstempels en met toegestane bulktoewijzing:
Voorbeeld van een minimaal Eloquent-model voor zoekopdrachten:
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;
}
Hier wordt aangegeven dat het model Pais bevindt zich in de standaard Laravel-naamruimteHet erft van Model en stelt je in staat om elk veld toe te wijzen met create() door de beveiligde array leeg te laten. Door tijdstempels uit te schakelen met public $timestamps = false, voorkom je problemen als de tabel de kolommen created_at en updated_at niet heeft.
De volgende stap is het definiëren de routes die zowel de weergave van de zoekmachine als de AJAX-verzoeken zullen verwerkenEen veelgebruikt schema combineert een GET-route om de weergave weer te geven en een POST-route die is ontworpen om realtime query's te ontvangen:
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']);
De root-route retourneert een welkomstweergave, terwijl de URL /search is gereserveerd voor zoekfunctionaliteitDe index()-methode van de controller geeft het formulier en de zoekopdracht weer, terwijl de search()-methode asynchrone verzoeken verwerkt die door de browser worden verzonden.
In de controller kun je een heel praktisch patroon implementeren: Maak een standaardresponsarray voor het geval er een fout optreedt en overschrijf het alleen als het daadwerkelijk een geldige AJAX-aanvraag is en de query zonder problemen wordt uitgevoerd.
De controller kan een vergelijkbare structuur dit:
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);
}
}
Op dit punt heb je al de volledige backendcyclus: binnenkomende AJAX-aanvraag, controleren of het AJAX is, query's uitvoeren met where like en resultaten beperken naar een redelijk aantal met behulp van take(10) om overbelasting van de database te voorkomen. De respons wordt altijd in JSON verzonden, wat het werk van de frontend aanzienlijk vereenvoudigt.
Blade view en JavaScript fetch voor reactief zoeken
Nu het model, de routes en de controller klaar zijn, is het tijd om het zichtbare gedeelte te bouwen: een formulier met een zoekveld en een blok om de resultaten weer te geven, plus de JavaScript die verantwoordelijk is voor het doen van verzoeken op de achtergrond.
Het Blade-overzicht kan heel eenvoudig zijn, afhankelijk van de CSRF-token die Laravel injecteert om POST-verzoeken te valideren en in een zoekopdracht die gemakkelijk te gebruiken is:
<!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 dit voorbeeld is het script Luister naar de keyup-gebeurtenis op de zoekinvoerElke toetsaanslag activeert een ophaalverzoek naar het /search-pad. De huidige tekst van het veld wordt verzonden in JSON-formaat en sleutelheaders zoals X-Requested-With worden toegevoegd om aan te geven dat het AJAX is, samen met het CSRF-token om de standaardbeveiliging van Laravel te omzeilen.
Zodra het antwoord binnenkomt, wordt het omgezet naar JSON en dynamisch gegenereerd. een kleine HTML-lijst met de resultatenof een melding als "Geen resultaten gevonden" wanneer de query geen gegevens oplevert. Dit alles zonder de pagina opnieuw te laden, op een natuurlijke manier voor de gebruiker.
Dit patroon kan verder worden verfijnd met kleine UX-details, zoals het toevoegen van een vertraging (debounce) tussen toetsaanslagen, een lader weergeven of netwerkfouten verwerken om te voorkomen dat de interface vastloopt als er iets misgaat.
Live zoeken met Laravel en AJAX met behulp van jQuery
Hoewel fetch tegenwoordig veel terrein heeft gewonnen, jQuery AJAX blijft erg populair in oudere projecten of in teams die het al geïmplementeerd hebben. Het idee is precies hetzelfde: vastleggen wat de gebruiker typt, een asynchrone aanvraag indienen en de DOM vernieuwen.
Een typische workflow met jQuery in Laravel voor live zoeken omvat doorgaans de volgende basisstappen: een specifieke route definiëren, een speciale controller aanmaken, de Blade-weergave bouwen met de zoekinvoer Voeg ten slotte de jQuery-code toe die AJAX activeert zodra deze wordt getypt.
Het proces werkt als volgt: wanneer de gebruiker begint met typen, jQuery stuurt een query naar de server met de zoekreeks. Laravel filtert de informatie in de database, retourneert een JSON met de overeenkomende resultaten en jQuery werkt een HTML-container op de pagina bij om de overeenkomsten weer te geven, alles binnen milliseconden.
Het voordeel van het gebruik van jQuery is dat Het vat de syntaxis van AJAX vrijwel samen En het is heel eenvoudig te lezen als je de bibliotheek al in je project hebt. Je voegt echter een extra afhankelijkheid toe die mogelijk niet nodig is als je met moderne JavaScript en native fetch kunt werken.
Realtime filteren en zoeken op de frontend met Alpine.js
Wanneer de weer te geven gegevens relatief klein zijn (bijvoorbeeld minder dan 50 artikelen), is het niet altijd de moeite waard om een backend met complexe zoekopdrachten in te stellen. In die gevallen is een zeer handige optie Filter direct in de browser met Alpine.js, zonder dat er verzoeken aan de server worden gedaan terwijl de gebruiker typt.
Het idee is om voor elk element vooraf een zoekreeks te berekenen (bijvoorbeeld naam, beschrijving en categorie in kleine letters), deze op te slaan in een data-search-text -attribuut en Alpine.js de rest te laten doen. elementen weergeven of verbergen op basis van de geschreven tekst in een zoekveld.
Het Alpine.js-component kan een vergelijkbare structuur hebben als deze: filterItems
{
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;
},
}
In het overzicht zou elke kaart of rij met gegevens een kenmerk bevatten data-search-text met de tekst al voorbereid in kleine lettersDaarom wordt het filter teruggebracht tot een includes()-functie in JavaScript, wat erg snel is voor korte lijsten:
<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>
Bovendien kunt u een leeg statusblok alleen weergeven wanneer Er zijn geen resultaten voor de huidige zoekterm.de gebruiker wordt uitgenodigd om de tekst aan te passen of het veld leeg te maken met een knop waarmee de zoekopdracht eenvoudigweg wordt teruggezet naar een lege tekenreeks.
Deze aanpak heeft duidelijke voordelen: Er vinden geen serveraanroepen plaats tijdens het zoeken.De interactie is vrijwel direct en de logica blijft zeer lokaal en gemakkelijk te debuggen. Het is perfect voor snelle selectors, itemselectie-modals of kleine catalogi die in een Laravel-pagina zijn ingebed.
Laravel Scout: zoeken in volledige tekst met gespecialiseerde engines
Als het serieus wordt en je hulp nodig hebt snelle, relevante en schaalbare full-text zoekopdrachtenHet natuurlijke pad in Laravel is Laravel Scout. Scout is een integratielaag waarmee je je Eloquent-modellen eenvoudig kunt verbinden met zoekmachines zoals Algolia, Meilisearch, je eigen database, in-memory collecties of zelfs Elasticsearch via externe controllers.
Om met Scout te beginnen is het gebruikelijk om: maak een nieuw Laravel-project of hergebruik een bestaand projectOm het te starten, gebruik je Docker (bijvoorbeeld met Laravel Sail) en installeer je vervolgens de bibliotheek met Composer. Publiceer vervolgens het configuratiebestand scout.php en pas de omgevingsvariabelen aan op basis van de driver die je wilt gebruiken.
Een typische workflow zou zijn om Scout te installeren met Composer, de configuratie ervan te publiceren en Activeer de indexeringswachtrij met SCOUT_QUEUE=true Zorg ervoor dat resource-intensieve bewerkingen in het .env-bestand op de achtergrond worden verwerkt, waardoor de responstijden van de applicatie worden verbeterd. Zorg er daarnaast voor dat DB_HOST verwijst naar de database die u gebruikt, wat vooral belangrijk is als u Docker-containers gebruikt.
Om als model deel te kunnen nemen aan Scout-zoektochten, is het noodzakelijk om: Om het expliciet als doorzoekbaar te markeren door de eigenschap Doorzoekbaar toe te voegenAls u bijvoorbeeld een treinmodel hebt dat een tabel met treinen met een titelveld vertegenwoordigt, kunt u dit als volgt definiëren:
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';
}
}
Met de doorzoekbareAs-methode kunt u: pas de indexnaam aan in de zoekmachineIn plaats van de standaardnaam te gebruiken die van het model is afgeleid, neemt Scout het over. Vanaf hier synchroniseert Scout de aanmaak-, update- en verwijderingsbewerkingen met de externe of lokale index, afhankelijk van de gekozen driver.
Laravel Scout met Algolia: razendsnelle SaaS-zoekfunctie
Algolia is een SaaS-service gericht op om zeer snelle en relevante zoekopdrachten in grote hoeveelheden data aan te biedenHet beschikt over een webpaneel voor het beheren van indexen, relevantieregels, synoniemen, etc. en integreert uitstekend met Laravel via Scout en de officiële PHP-client.
Om Algolia met Scout te gebruiken, moet u de PHP-client met Composer installeren, uw referenties registreren in het .env-bestand (toepassings-ID en beheerders-API-sleutel) en stel SCOUT_DRIVER=algolia in om Scout te vertellen deze engine te gebruiken. Via het Algolia-paneel kunt u zowel de applicatie-ID als de beheerderssleutel verkrijgen.
Zodra de omgeving is geconfigureerd, kunt u methoden gebruiken zoals Train::search('tekst')->paginate(6) rechtstreeks in uw controllers om zoekopdrachten uit te voeren op de geïndexeerde velden. U ontvangt de resultaten in gepagineerde Eloquent-indeling die u direct kunt doorgeven aan een Blade-weergave.
Bijv.Je zou een controller kunnen hebben index die alle treinen weergeeft of een zoekopdracht uitvoert als een titlesearch-parameter wordt ontvangen, en een create-methode om nieuwe treinen in de index in te voegen:
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();
}
In het bijbehorende overzicht kunt u combineren een formulier voor het registreren van nieuwe treinen en nog een GET-formulier met een veld voor titelzoekopdracht dat de zoekopdracht activeert bij het indienen. Vervolgens hoef je alleen nog maar door de verzameling treinen te itereren en hun velden in een tabel weer te geven, gebruikmakend van de paginalinks die Laravel genereert.
Verkennen met Meilisearch, database en collecties
Als u externe diensten liever vermijdt, Meilisearch is een open source zoekmachine die u lokaal of op uw infrastructuur kunt implementeren. Scout integreert met Meilisearch op een vergelijkbare manier als Algolia, door simpelweg de driver te wijzigen en de variabelen MEILISEARCH_HOST en MEILISEARCH_KEY toe te voegen aan het .env-bestand.
Om het te gebruiken, installeert u de Meilisearch PHP-client, past u deze aan SCOUT_DRIVER=meilisearch en wijs MEILISEARCH_HOST naar de URL van de instantie (bijvoorbeeld http://127.0.0.1:7700). Als u al eerdere records had, kunt u deze indexeren met de opdracht php artisan scout:import "App\Models\Train", zodat de engine ze beschikbaar heeft.
Bij kleinere of middelgrote toepassingen kunt u ook kiezen voor de Scout-driverdatabaseDit maakt gebruik van volledige tekstindexen en LIKE-opdrachten op uw MySQL- of PostgreSQL-database. In dit geval hebt u geen externe service nodig; stel SCOUT_DRIVER=database in zodat Scout de database zelf als zoekmachine gebruikt.
Een andere interessante optie is de drivercollectie, die werkt op Eloquent-collecties in het geheugenDeze engine filtert resultaten met behulp van WHERE-clausules en verzamelingsfiltering en is compatibel met elke database die door Laravel wordt ondersteund. Je kunt hem activeren met `SCOUT_DRIVER=collection` of door het Scout-configuratiebestand aan te passen voor meer specifieke instellingen.
Integratie met Elasticsearch met behulp van Explorer
Als uw zoekbehoeften betrekking hebben op werken met enorme hoeveelheden data en realtime-analyseElasticsearch is een klassieker. In het Laravel-ecosysteem is een moderne manier om het te integreren met Scout het gebruik van de Explorer-controller. Deze fungeert als brug tussen je modellen en een Elasticsearch-cluster.
Hiervoor wordt meestal Docker gebruikt, samen met een uitgebreid docker-compose-bestand dat, naast de typische services (Laravel, MySQL, Redis, Meilisearch, enz.), Elasticsearch- en Kibana-containersVervolgens installeert u het pakket jeroen-g/explorer via Composer en publiceert u het configuratiebestand om aan te geven welke modellen moeten worden geïndexeerd.
In het bestand config/explorer.php kunt u uw modellen registreren onder de indexes-sleutel, bijvoorbeeld door het volgende toe te voegen: App\Modellen\Trein::klasseDaarnaast wijzigt u de Scout-driver in het .env-bestand naar elastic met SCOUT_DRIVER=elastic, zodat alles naar Elasticsearch verwijst.
Binnen het Train-model moet de Explored-interface worden geïmplementeerd en moet de methode worden overschreven. toewijsbaarAlsdie de map definieert van de velden die naar de index worden verzonden. Een minimaal voorbeeld zou zijn:
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,
];
}
}
Van nu af aan, U kunt zoekopdrachten op Elasticsearch starten met behulp van dezelfde Scout-interface., waarbij gebruik wordt gemaakt van de zeer lage responstijden en de volledige querykracht van deze engine, zonder het Laravel-ecosysteem te verlaten.
Met al deze benaderingen – van eenvoudige autocomplete met fetch of jQuery, tot frontend-filtering met Alpine.js, tot full-text zoekopdrachten met Laravel Scout en diverse drivers – Laravel biedt je een enorm scala aan opties voor het implementeren van realtime zoekopdrachten afgestemd op de omvang van uw project, de prestaties die u nodig hebt en de infrastructuur die u wilt onderhouden.
Inhoud
- Wat is een realtime zoekopdracht in Laravel en hoe werkt het in de basis?
- Model, routes en controller voor een eenvoudige realtime zoekmachine
- Blade view en JavaScript fetch voor reactief zoeken
- Live zoeken met Laravel en AJAX met behulp van jQuery
- Realtime filteren en zoeken op de frontend met Alpine.js
- Laravel Scout: zoeken in volledige tekst met gespecialiseerde engines
- Laravel Scout met Algolia: razendsnelle SaaS-zoekfunctie
- Verkennen met Meilisearch, database en collecties
- Integratie met Elasticsearch met behulp van Explorer