- Mit Laravel können Sie alles implementieren, von einfachen Suchmaschinen mit AJAX bis hin zu erweiterten Volltextsuchen mit Laravel Scout und externen Suchmaschinen wie Algolia, Meilisearch oder Elasticsearch.
- Bei einfachen Suchvorgängen vermeidet das Filtern im Frontend mit Alpine.js oder mit nativen Fetch-Anfragen eine Überlastung des Servers und verbessert die Benutzerfreundlichkeit bei kleinen Listen.
- Laravel Scout zentralisiert die Integration mit verschiedenen Suchmaschinen und vereinfacht das Kennzeichnen von Modellen als durchsuchbar, die Verwaltung von Indizes und das einheitliche Starten von Abfragen.
- Die Wahl der Engine (SaaS, Open Source oder Datenbank) sollte auf dem Datenvolumen, der Komplexität der Suchvorgänge sowie den Leistungs- und Wartungsanforderungen des Projekts basieren.
Wenn Sie mit Laravel arbeiten und eine Echtzeit-Suchmaschine benötigen, die sofort reagiert , kann man leicht den Überblick über die unzähligen Möglichkeiten verlieren: AJAX mit fetch, jQuery, Alpine.js, Scout mit Algolia oder Meilisearch, Frontend-Filterung usw. Die gute Nachricht: Das Laravel-Ökosystem bietet bereits praktisch alles, was Sie für den Aufbau einer reibungslosen und schnellen Suchmaschine benötigen, ohne sich überfordert zu fühlen.
In diesem Artikel erfahren Sie, wie Sie verschiedene Arten der Echtzeitsuche in Laravel implementieren – von der klassischen AJAX-Autovervollständigung bis hin zur Volltextsuche mit Laravel Scout und Suchmaschinen wie Algolia, Meilisearch, der Datenbank selbst oder sogar Elasticsearch. Außerdem lernen Sie schlanke Alternativen mit Alpine.js kennen, um Daten bei kleinen Datensätzen direkt im Browser zu filtern.
Was ist eine Echtzeitsuche in Laravel und wie funktioniert sie im Prinzip?
Die Idee hinter der Echtzeitsuche besteht darin, dass beim Eingeben eines Textes durch den Nutzer eine Suchanfrage ausgelöst und die Ergebnisse aktualisiert werden, ohne dass die Seite neu geladen werden muss. Technisch gesehen sind dafür drei Schlüsselkomponenten erforderlich: das Laravel-Backend, das JavaScript des Browsers und der Datenaustausch im JSON-Format.
Einerseits fungiert Laravel als Serverschicht , die Anfragen empfängt, Suchparameter (den eingegebenen Text) interpretiert, die Datenbank abfragt und eine strukturierte Antwort, üblicherweise im JSON-Format, zurückgibt. Diese Antwort kann Erfolg, einen Fehler oder das Fehlen von Ergebnissen signalisieren.
Auf der anderen Seite übernimmt JavaScript das Abhören von Benutzeraktionen im Suchfeld, das Senden asynchroner Anfragen (AJAX) an den Backend-Server und das Rendern der zurückgegebenen Daten auf der Seite, ohne dass ein vollständiges Neuladen des Browsers erforderlich ist. Dies kann mit nativem Fetch, jQuery AJAX oder kleinen reaktiven Bibliotheken wie Alpine.js realisiert werden.
Mit diesem grundlegenden Mechanismus können Sie alles Mögliche erstellen, von einer einfachen Autovervollständigung mit wenigen Datensätzen bis hin zu einer fortschrittlichen Volltextsuchmaschine mit Relevanz, Paginierung und Filtern, wobei Sie auf Bibliotheken wie Laravel Scout und externe Suchmaschinen zurückgreifen, die für Suchvorgänge optimiert sind.
Modell, Routen und Controller für eine einfache Echtzeit-Suchmaschine
Bevor Sie sich mit JavaScript beschäftigen, muss die Laravel-Seite gut organisiert sein: ein Eloquent-Modell für die Suche, klare Routen und ein Controller, der sich um die Verarbeitung der Suchlogik in Echtzeit kümmert.
Der erste Schritt besteht darin, ein Eloquent-Modell zu erstellen, das die Tabelle repräsentiert, in der Sie suchen möchten. Stellen Sie sich eine Tabelle mit Ländern und ein sehr einfaches Modell namens „Land“ vor , das keine Zeitstempel enthält und bei dem Massenzuweisungen erlaubt sind:
Beispiel eines minimalen Eloquent-Modells für Suchvorgänge :
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;
}
Dies bedeutet, dass sich das Pais-Modell im Standard-Namespace von Laravel befindet , von Model erbt und es ermöglicht, beliebige Felder mit `create()` zuzuweisen, indem das geschützte Array leer gelassen wird. Durch Deaktivieren der Zeitstempel mit `public $timestamps = false` vermeiden Sie Probleme, falls die Tabelle die Spalten `created_at` und `updated_at` nicht enthält.
Im nächsten Schritt werden die Routen definiert, die sowohl die Suchmaschinenanzeige als auch AJAX-Anfragen verarbeiten . Ein sehr gängiges Schema kombiniert eine GET-Route zur Anzeige der Ansicht mit einer POST-Route, die für den Empfang von Anfragen in Echtzeit zuständig ist:
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']);
Die Hauptroute (Root Route) zeigt eine Willkommensseite an, während die URL `/search` für die Suchfunktion reserviert ist . Die `index()`-Methode des Controllers zeigt das Formular und das Suchfeld an, während die `search()`-Methode asynchrone Anfragen des Browsers verarbeitet.
Im Controller können Sie ein sehr praktisches Muster implementieren: Bereiten Sie ein Standard-Antwort-Array für den Fehlerfall vor und überschreiben Sie es nur dann, wenn es sich tatsächlich um eine gültige AJAX-Anfrage handelt und die Abfrage problemlos ausgeführt wird.
Der Controller könnte eine ähnliche Struktur wie diese haben:
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);
}
}
An diesem Punkt ist der gesamte Backend-Zyklus abgeschlossen : eingehende AJAX-Anfrage, Überprüfung, ob es sich tatsächlich um eine AJAX-Anfrage handelt, Abfrage mit `where like` und Begrenzung der Ergebnisanzahl auf ein sinnvolles Maß mit `take(10)`, um eine Überlastung der Datenbank zu vermeiden. Die Antwort wird stets im JSON-Format gesendet, was die Arbeit im Frontend erheblich vereinfacht.
Blade-Ansicht und JavaScript-Abruf für reaktive Suche
Nachdem Modell, Routen und Controller bereit sind, ist es an der Zeit, den sichtbaren Teil zu erstellen: ein Formular mit einem Suchfeld und einem Block zur Anzeige der Ergebnisse sowie das JavaScript, das für die Durchführung der Anfragen im Hintergrund zuständig ist.
Die Blade-Ansicht kann sehr einfach sein und sich auf das von Laravel eingefügte CSRF-Token zur Validierung von POST-Anfragen sowie auf ein benutzerfreundliches Suchfeld stützen:
<!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 diesem Beispiel überwacht das Skript das Keyup-Ereignis des Suchfelds . Jeder Tastendruck löst eine Fetch-Anfrage an den Pfad `/search` aus. Der aktuelle Text des Felds wird im JSON-Format gesendet, und wichtige Header wie `X-Requested-With` kennzeichnen die AJAX-Anfrage. Zusätzlich wird ein CSRF-Token gesendet, um den nativen Schutz von Laravel zu umgehen.
Sobald die Antwort eintrifft, wird sie in JSON umgewandelt und eine kleine HTML-Liste mit den Ergebnissen dynamisch generiert . Falls die Abfrage keine Daten liefert, wird eine Meldung wie „Keine Ergebnisse gefunden“ angezeigt. All dies geschieht, ohne die Seite neu zu laden – ganz intuitiv für den Nutzer.
Dieses Muster kann durch kleine UX-Details weiter verfeinert werden, wie z. B. durch Hinzufügen einer Entprellung zwischen den Tastendrücken, Anzeigen eines Ladebildschirms oder Behandeln von Netzwerkfehlern, um zu verhindern, dass die Benutzeroberfläche eingefroren erscheint, wenn etwas schiefgeht.
Live-Suche mit Laravel und AJAX mithilfe von jQuery
Obwohl Fetch deutlich an Bedeutung gewonnen hat, ist jQuery AJAX in älteren Projekten oder Teams, die es bereits integriert haben, weiterhin sehr beliebt. Das Prinzip ist genau dasselbe: Die Benutzereingaben werden erfasst, eine asynchrone Anfrage gesendet und das DOM aktualisiert.
Ein typischer Workflow mit jQuery in Laravel für eine Live-Suche umfasst in der Regel diese grundlegenden Schritte: eine bestimmte Route definieren, einen dedizierten Controller erstellen, die Blade-Ansicht mit dem Sucheingabefeld erstellen und schließlich den jQuery-Code hinzufügen, der beim Eingeben des Suchfelds einen AJAX-Aufruf auslöst.
Der Prozess funktioniert folgendermaßen: Sobald der Benutzer mit der Eingabe beginnt, sendet jQuery eine Anfrage mit dem Suchbegriff an den Server. Laravel filtert die Informationen in der Datenbank, gibt ein JSON-Objekt mit den passenden Ergebnissen zurück, und jQuery aktualisiert einen HTML-Container auf der Seite, um die Treffer anzuzeigen – alles innerhalb weniger Millisekunden.
Der Vorteil von jQuery liegt in der stark vereinfachten AJAX-Syntax und der einfachen Lesbarkeit, sofern die Bibliothek bereits im Projekt vorhanden ist. Allerdings führt jQuery eine zusätzliche Abhängigkeit ein, die unter Umständen nicht notwendig ist, wenn man mit modernem JavaScript und nativen Fetch-Funktionen arbeitet.
Echtzeitfilterung und -suche im Frontend mit Alpine.js
Bei einer relativ geringen Datenmenge (z. B. weniger als 50 Einträge ) lohnt sich der Aufbau eines Backends mit komplexen Suchfunktionen nicht immer. In solchen Fällen bietet sich die Filterung direkt im Browser mit Alpine.js an , ohne während der Eingabe Anfragen an den Server zu senden.
Die Idee besteht darin, für jedes Element eine Suchzeichenfolge vorzuberechnen (z. B. Name, Beschreibung und Kategorie in Kleinbuchstaben), diese in einem data-search-text-Attribut zu speichern und Alpine.js die Anzeige oder das Ausblenden von Elementen basierend auf dem in einem Suchfeld eingegebenen Text verwalten zu lassen.
Die Alpine.js-Komponente kann eine ähnliche Struktur wie diese haben: 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 der Ansicht hätte jede Karte oder Datenzeile ein data-search-text-Attribut mit dem bereits in Kleinbuchstaben vorbereiteten Text , sodass der Filter in JavaScript auf includes() reduziert wird, was bei kurzen Listen sehr schnell ist:
<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>
Darüber hinaus können Sie einen leeren Statusblock nur dann anzeigen lassen, wenn für den aktuellen Suchbegriff keine Ergebnisse vorliegen . So können Sie den Benutzer auffordern, den Text zu ändern oder das Feld mit einer Schaltfläche zu leeren, die die Suche einfach auf eine leere Zeichenfolge zurücksetzt.
Dieser Ansatz bietet klare Vorteile: Während der Suche erfolgen keine Serveraufrufe , die Interaktion ist nahezu verzögerungsfrei und die Logik bleibt lokal und ist leicht zu debuggen. Er eignet sich perfekt für Schnellauswahldialoge, Artikelauswahlfenster oder kleine Kataloge, die in eine Laravel-Seite eingebettet sind.
Laravel Scout: Volltextsuche mit spezialisierten Suchmaschinen
Wenn es darauf ankommt und Sie eine schnelle, relevante und skalierbare Volltextsuche benötigen , ist Laravel Scout in Laravel die naheliegende Wahl. Scout ist eine Integrationsschicht, mit der Sie Ihre Eloquent-Modelle einfach mit Suchmaschinen wie Algolia, Meilisearch, Ihrer Datenbank, In-Memory-Sammlungen oder sogar Elasticsearch über externe Controller verbinden können.
Um Scout zu verwenden, erstellt man üblicherweise ein neues Laravel-Projekt oder nutzt ein bestehendes wieder , startet es mit Docker (z. B. mit Laravel Sail) und installiert anschließend die Bibliothek mit Composer. Danach veröffentlicht man die Konfigurationsdatei scout.php und passt die Umgebungsvariablen an den gewünschten Treiber an.
Ein typischer Workflow sieht so aus: Scout wird mit Composer installiert, die Konfiguration veröffentlicht und die Indexierungswarteschlange mit `SCOUT_QUEUE=true` in der `.env`-Datei aktiviert. Dadurch werden ressourcenintensive Operationen im Hintergrund verarbeitet, was die Antwortzeiten der Anwendung verbessert. Zusätzlich sollte sichergestellt werden, dass `DB_HOST` auf die verwendete Datenbank verweist. Dies ist besonders wichtig bei der Verwendung von Docker-Containern.
Damit ein Modell an Scout-Suchen teilnehmen kann, muss es explizit als durchsuchbar gekennzeichnet werden, indem das Merkmal `Searchable` hinzugefügt wird . Wenn Sie beispielsweise ein `Train`-Modell haben, das eine Tabelle von Zügen mit einem Feld `title` darstellt, könnten Sie es wie folgt definieren:
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';
}
}
Die Methode `searchableAs` ermöglicht es Ihnen , den Indexnamen in der Suchmaschine anzupassen , anstatt den vom Modell abgeleiteten Standardnamen zu verwenden. Scout synchronisiert anschließend Erstellungs-, Aktualisierungs- und Löschvorgänge mit dem Remote- oder lokalen Index, abhängig vom gewählten Treiber.
Laravel Scout mit Algolia: Blitzschnelle SaaS-Suche
Algolia ist ein SaaS-Dienst, der sich auf die Bereitstellung sehr schneller und relevanter Suchvorgänge in großen Datenmengen spezialisiert hat . Er bietet ein Webpanel zur Verwaltung von Indizes, Relevanzregeln, Synonymen und mehr und lässt sich nahtlos über Scout und den offiziellen PHP-Client in Laravel integrieren.
Um Algolia mit Scout zu verwenden, müssen Sie den PHP-Client mit Composer installieren, Ihre Zugangsdaten (Anwendungs-ID und Admin-API-Schlüssel) in der .env-Datei registrieren und SCOUT_DRIVER=algolia konfigurieren, damit Scout diese Engine verwendet. Die Anwendungs-ID und den Admin-Schlüssel finden Sie im Algolia-Dashboard.
Sobald die Umgebung eingerichtet ist, können Sie Methoden wie Train::search('text')->paginate(6) direkt in Ihren Controllern verwenden, um Suchvorgänge in den indizierten Feldern durchzuführen und Ergebnisse im paginierten Eloquent-Format zu erhalten, die dann an eine Blade-Ansicht übergeben werden können.
Beispielsweise könnte man einen Index- Controller haben , der alle Züge auflistet oder eine Suche durchführt, wenn ein Titelsuchparameter übergeben wird, und eine Erstellungsmethode, um neue Züge in den Index einzufügen:
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 der entsprechenden Ansicht können Sie ein Formular zum Hinzufügen neuer Züge und ein weiteres GET-Formular mit einem Titelsuchfeld kombinieren, das die Suche beim Absenden auslöst. Anschließend durchlaufen Sie einfach die Zugliste und zeigen deren Felder in einer Tabelle an, wobei Sie die von Laravel generierten Paginierungslinks nutzen.
Scout mit Meilisearch, Datenbanken und Sammlungen
Wenn Sie externe Dienste vermeiden möchten, ist Meilisearch eine Open-Source-Suchmaschine , die Sie lokal oder auf Ihrer Infrastruktur einsetzen können. Scout integriert Meilisearch auf sehr ähnliche Weise wie Algolia, indem einfach der Treiber geändert und die Variablen MEILISEARCH_HOST und MEILISEARCH_KEY zur .env-Datei hinzugefügt werden.
Um Meilisearch zu verwenden, installieren Sie den Meilisearch-PHP-Client, setzen Sie SCOUT_DRIVER=meilisearch und verweisen Sie MEILISEARCH_HOST auf die Instanz-URL (z. B. http://127.0.0.1:7700). Falls bereits Datensätze vorhanden sind, können Sie diese mit dem Befehl `php artisan scout:import "App\Models\Train"` indizieren, sodass sie der Engine zur Verfügung stehen.
Für kleinere oder mittelgroße Anwendungen können Sie auch den Datenbanktreiber von Scout wählen , der Volltextindizes und LIKE-Anweisungen Ihrer MySQL- oder PostgreSQL-Datenbank nutzt. In diesem Fall benötigen Sie keinen externen Dienst; setzen Sie einfach `SCOUT_DRIVER=database`, damit Scout die Datenbank selbst als Suchmaschine verwendet.
Eine weitere interessante Option ist der Collection Driver, der mit Eloquent-Collections im Arbeitsspeicher arbeitet . Diese Engine filtert Ergebnisse mithilfe von `where`-Klauseln und Collection-Filtermethoden und ist mit allen von Laravel unterstützten Datenbanken kompatibel. Sie können ihn mit `SCOUT_DRIVER=collection` aktivieren oder, falls gewünscht, die Scout-Konfigurationsdatei anpassen.
Integration mit Elasticsearch mithilfe von Explorer
Wenn Sie mit riesigen Datenmengen und Echtzeitanalysen arbeiten müssen , ist Elasticsearch ein Klassiker. Im Laravel-Ökosystem lässt es sich modern mit Scout über den Explorer-Controller integrieren, der als Schnittstelle zwischen Ihren Modellen und einem Elasticsearch-Cluster fungiert.
Dies beinhaltet typischerweise die Arbeit mit Docker und einer umfangreichen docker-compose-Datei, die neben den üblichen Diensten (Laravel, MySQL, Redis, Meilisearch usw.) auch Elasticsearch- und Kibana-Container startet . Anschließend installieren Sie das Paket jeroen-g/explorer über Composer und veröffentlichen dessen Konfigurationsdatei, um festzulegen, welche Modelle indiziert werden sollen.
In der Datei `config/explorer.php` können Sie Ihre Modelle unter dem Schlüssel `indexes` registrieren, beispielsweise durch Hinzufügen von `App\Models\Train::class` . Zusätzlich ändern Sie den Treiber in der Datei `.env` von Scout auf Elasticsearch mit `SCOUT_DRIVER=elastic`, sodass alles auf Elasticsearch verweist.
Innerhalb des Train-Modells müssen Sie die Explored-Schnittstelle implementieren und die mappableAs -Methode überschreiben , welche die Zuordnung der Felder definiert, die an den Index gesendet werden sollen. Ein Minimalbeispiel wäre:
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,
];
}
}
Von hier aus können Sie Suchvorgänge in Elasticsearch mit derselben Scout-Oberfläche starten und dabei von sehr kurzen Antwortzeiten und der vollen Abfrageleistung dieser Engine profitieren, ohne das Laravel-Ökosystem zu verlassen.
Mit all diesen Ansätzen – von der einfachen Autovervollständigung mit fetch oder jQuery über die Frontend-Filterung mit Alpine.js bis hin zur Volltextsuche mit Laravel Scout und verschiedenen Treibern – bietet Laravel Ihnen eine riesige Auswahl an Möglichkeiten zur Implementierung von Echtzeitsuchen, die auf die Größe Ihres Projekts, die benötigte Leistung und die Infrastruktur, die Sie pflegen möchten, zugeschnitten sind.