Kompletny przewodnik po wyszukiwaniu w czasie rzeczywistym w Laravel

Ostatnia aktualizacja: 5 grudnia 2025
  • Laravel umożliwia implementację wszystkiego, od prostych wyszukiwarek z wykorzystaniem AJAX po zaawansowane wyszukiwanie pełnotekstowe z wykorzystaniem Laravel Scout i zewnętrznych wyszukiwarek, takich jak Algolia, Meilisearch lub Elasticsearch.
  • W przypadku lekkich wyszukiwań filtrowanie w interfejsie użytkownika za pomocą Alpine.js lub natywnych żądań pobierania pozwala uniknąć przeciążenia serwera i usprawnia korzystanie z małych list.
  • Laravel Scout centralizuje integrację z różnymi wyszukiwarkami i ułatwia oznaczanie modeli jako możliwych do wyszukiwania, zarządzanie indeksami i jednolite uruchamianie zapytań.
  • Wybór silnika (SaaS, open source lub baza danych) powinien zależeć od objętości danych, złożoności wyszukiwań oraz wymagań dotyczących wydajności i konserwacji projektu.

wyszukiwanie w czasie rzeczywistym w Laravel

Kiedy zaczynasz pracę z Laravel i potrzebujesz wyszukiwarka działająca w czasie rzeczywistym, która reaguje natychmiastŁatwo się pogubić wśród tysiąca możliwych podejść: AJAX z pobieraniem, jQuery, Alpine.js, Scout z Algolią lub Meilisearch, filtrowanie front-endu itd. Dobra wiadomość jest taka, że ​​ekosystem Laravel zapewnia już praktycznie wszystko, czego potrzebujesz, aby skonfigurować płynne i szybkie wyszukiwanie bez porażek w trakcie próby.

W tym artykule zobaczysz jak złożyć różne typy wyszukiwania w czasie rzeczywistym w LaravelOd klasycznego autouzupełniania AJAX po wyszukiwanie pełnotekstowe w Laravel Scout i wyszukiwarkach takich jak Algolia, Meilisearch, samej bazie danych, a nawet Elasticsearch. Zobaczysz również lekkie alternatywy z Alpine.js do filtrowania danych bezpośrednio w przeglądarce, gdy ich wolumen jest niewielki.

Czym jest wyszukiwanie w czasie rzeczywistym w Laravel i jak działają jego podstawy?

Idea stojąca za wyszukiwaniem w czasie rzeczywistym polega na tym, że gdy użytkownik wpisuje tekst w polu tekstowymZapytanie jest uruchamiane, a wyniki aktualizowane bez przeładowywania strony. Technicznie rzecz biorąc, obejmuje to trzy kluczowe komponenty: zaplecze Laravel, JavaScript przeglądarki oraz wymianę danych w formacie JSON.

Z jednej strony Laravel działa jako warstwa serwerowa Odpowiada za odbieranie żądań, interpretowanie parametrów wyszukiwania (wprowadzonego tekstu), przeszukiwanie bazy danych i zwracanie ustrukturyzowanej odpowiedzi, zazwyczaj w formacie JSON. Odpowiedź ta może wskazywać na powodzenie, błąd lub brak wyników.

Na drugim końcu, JavaScript odpowiada za nasłuchiwanie zdarzeń użytkownika. W polu wyszukiwania wysyłaj żądania asynchroniczne (AJAX) do zaplecza i wyświetlaj zwrócone dane na stronie bez konieczności pełnego odświeżania strony przez przeglądarkę. Można to zrobić za pomocą natywnego pobierania, jQuery AJAX lub małych bibliotek reaktywnych, takich jak Alpine.js.

Za pomocą tego podstawowego mechanizmu możesz zbudować z Proste automatyczne uzupełnianie z kilkoma rekordami, aż po zaawansowaną wyszukiwarkę pełnotekstową z uwzględnieniem trafności, paginacji i filtrów, obsługiwaną przez biblioteki takie jak Laravel Scout i zewnętrzne wyszukiwarki zoptymalizowane pod kątem wyszukiwania.

Model, trasy i kontroler dla podstawowej wyszukiwarki czasu rzeczywistego

Zanim zagłębisz się w JavaScript, musisz upewnić się, że strona Laravel jest dobrze zorganizowana: model Eloquent do wyszukiwania, jasne trasy i dedykowany kontroler aby zarządzać logiką wyszukiwania w czasie rzeczywistym.

Pierwszym krokiem jest stworzenie modelu Eloquent reprezentującego tabelę, w której będziesz przeszukiwać. Wyobraź sobie tabelę krajów i model o nazwie Kraj Bardzo proste, bez znaczników czasu i z możliwością masowego przypisywania:

Przykład minimalnego modelu Eloquent dla wyszukiwań:

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

W tym miejscu wskazano, że model Pais znajduje się w standardowej przestrzeni nazw LaravelDziedziczy po modelu i pozwala na przypisanie dowolnego pola za pomocą funkcji create() poprzez pozostawienie tablicy chronionej pustej. Wyłączając znaczniki czasu za pomocą public $timestamps = false, unikniesz problemów, jeśli tabela nie ma kolumn created_at i updated_at.

Następnym krokiem jest zdefiniowanie trasy, które będą obsługiwać zarówno wyświetlanie w wyszukiwarce, jak i żądania AJAXBardzo powszechnym schematem jest połączenie trasy GET służącej do wyświetlania widoku i trasy POST przeznaczonej do odbierania zapytań w czasie rzeczywistym:

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

Trasa główna zwraca widok powitalny, podczas gdy adres URL /search jest zarezerwowane dla funkcji wyszukiwaniaMetoda index() kontrolera wyświetla formularz i pole wyszukiwania, podczas gdy metoda search() przetwarza asynchroniczne żądania wysyłane z przeglądarki.

W kontrolerze można zaimplementować bardzo praktyczny wzorzec: Przygotuj domyślną tablicę odpowiedzi na wypadek błędu i nadpisz je tylko wtedy, gdy rzeczywiście będzie to prawidłowe żądanie AJAX, a zapytanie zostanie wykonane bez problemów.

Kontroler może mieć podobna struktura to:

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

W tym momencie już masz pełny cykl zaplecza: przychodzące żądanie AJAX, sprawdzanie, czy jest to żądanie AJAX, wykonywanie zapytań z uwzględnieniem tego, co jest w porządku i ograniczanie wyników do rozsądnej liczby za pomocą take(10), aby uniknąć przeciążenia bazy danych. Odpowiedź jest zawsze wysyłana w formacie JSON, co znacznie upraszcza pracę frontendu.

Widok Blade i pobieranie JavaScript do reaktywnego wyszukiwania

Mając już gotowy model, trasy i kontroler, czas na zbudowanie widocznej części: formularz z polem wyszukiwania i blokiem do wyświetlania wynikóworaz JavaScript odpowiedzialny za wykonywanie żądań w tle.

Widok Blade może być bardzo prosty, opierając się na Token CSRF który Laravel wstrzykuje w celu walidacji żądań POST i w wygodnym w użyciu polu wyszukiwania:

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

W tym przykładzie skrypt Nasłuchuj zdarzenia keyup na wejściu wyszukiwaniaKażde naciśnięcie klawisza wyzwala żądanie pobrania do ścieżki /search. Aktualny tekst pola jest wysyłany w formacie JSON, a nagłówki, takie jak X-Requested-With, wskazują na AJAX, wraz z tokenem CSRF, który pozwala ominąć natywną ochronę Laravela.

Po otrzymaniu odpowiedzi jest ona przekształcana do formatu JSON i generowana dynamicznie. mała lista HTML z wynikamilub komunikat „Nie znaleziono wyników”, gdy zapytanie nie zwróci danych. Wszystko to bez przeładowywania strony, w sposób naturalny dla użytkownika.

Ten wzorzec można dodatkowo udoskonalić, dodając drobne szczegóły UX, takie jak opóźnienie (odbicie) pomiędzy naciśnięciami klawiszy wyświetl program ładujący lub obsługuj błędy sieciowe, aby zapobiec zawieszaniu się interfejsu w przypadku awarii.

Wyszukiwanie na żywo z Laravel i AJAX przy użyciu jQuery

Chociaż fetch zyskał obecnie dużą popularność, jQuery AJAX pozostaje bardzo popularny W starszych projektach lub w zespołach, które już ją zaimplementowały. Idea jest dokładnie taka sama: przechwytywanie wpisów użytkownika, wysyłanie asynchronicznego żądania i odświeżanie DOM.

Typowy przepływ pracy z jQuery w Laravel w przypadku wyszukiwania na żywo zazwyczaj obejmuje następujące podstawowe kroki: zdefiniuj konkretną trasę, utwórz dedykowany kontroler, zbuduj widok Blade z danymi wejściowymi wyszukiwania Na koniec dodaj kod jQuery, który uruchamia AJAX w momencie jego wpisania.

Proces wygląda następująco: gdy użytkownik zaczyna pisać, jQuery wysyła zapytanie do serwera z ciągiem wyszukiwania. Laravel filtruje informacje w bazie danych, zwraca JSON z pasującymi wynikami, a jQuery aktualizuje kontener HTML na stronie, aby odzwierciedlić dopasowania – wszystko w ciągu milisekund.

Zaletą korzystania z jQuery jest to, że W zasadzie podsumowuje składnię AJAX Jest to bardzo proste w odczycie, jeśli masz już bibliotekę w swoim projekcie. Dodajesz jednak dodatkową zależność, która może być zbędna, jeśli potrafisz pracować z nowoczesnym JavaScriptem i natywnym pobieraniem.

Filtrowanie i wyszukiwanie w czasie rzeczywistym w interfejsie użytkownika za pomocą Alpine.js

Gdy wyświetlane dane są stosunkowo niewielkie (np. mniej niż 50 XNUMX pozycji), nie zawsze warto konfigurować zaplecza ze złożonymi wyszukiwaniami. W takich przypadkach bardzo wygodną opcją jest Filtruj bezpośrednio w przeglądarce za pomocą Alpine.js, bez wysyłania żądań do serwera podczas pisania przez użytkownika.

Pomysł polega na wstępnym obliczeniu ciągu wyszukiwania dla każdego elementu (na przykład nazwy, opisu i kategorii pisanych małymi literami), zapisaniu go w atrybucie data-search-text i pozwoleniu Alpine.js na zajęcie się resztą. pokaż lub ukryj elementy zgodnie z tekstem pisanym w polu wyszukiwania.

Komponent Alpine.js może mieć strukturę podobną do tej: elementy filtra

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

W widoku każda karta lub wiersz danych będzie zawierał atrybut wyszukiwanie-danych-tekst z już przygotowanym tekstem w małych literachDlatego filtr został zredukowany do funkcji include() w JavaScript, która jest bardzo szybka w przypadku krótkich list:

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

Dodatkowo możesz wyświetlić pusty blok stanu tylko wtedy, gdy Brak wyników wyszukiwania dla bieżącego terminu.zachęcając użytkownika do modyfikacji tekstu lub wyczyszczenia pola za pomocą przycisku, który po prostu resetuje wyszukiwanie do pustego ciągu.

Takie podejście ma wyraźne zalety: Podczas wyszukiwania nie ma żadnych wywołań serwera.Interakcja jest praktycznie natychmiastowa, a logika pozostaje wysoce lokalna i łatwa do debugowania. Idealnie nadaje się do szybkich selektorów, okien modalnych wyboru elementów lub małych katalogów osadzonych na stronie Laravel.

Laravel Scout: wyszukiwanie pełnotekstowe z wykorzystaniem specjalistycznych silników

Kiedy sprawy stają się poważne i potrzebujesz szybkie, trafne i skalowalne wyszukiwanie pełnotekstoweNaturalną ścieżką w Laravel jest Laravel Scout. Scout to warstwa integracyjna, która pozwala łatwo połączyć modele Eloquent z wyszukiwarkami takimi jak Algolia, Meilisearch, własną bazą danych, kolekcjami w pamięci, a nawet Elasticsearch za pośrednictwem zewnętrznych kontrolerów.

Aby rozpocząć korzystanie ze Scouta, należy wykonać standardową czynność: utwórz nowy projekt Laravel lub wykorzystaj istniejącyAby go uruchomić, użyj Dockera (na przykład z Laravel Sail), a następnie zainstaluj bibliotekę za pomocą Composera. Po wykonaniu tej czynności opublikuj plik konfiguracyjny scout.php i dostosuj zmienne środowiskowe do sterownika, którego chcesz użyć.

Typowy przepływ pracy polegałby na zainstalowaniu Scouta za pomocą Composera, opublikowaniu jego konfiguracji i aktywuj kolejkę indeksowania za pomocą SCOUT_QUEUE=true W pliku .env upewnij się, że operacje wymagające dużej ilości zasobów są przetwarzane w tle, co skróci czas reakcji aplikacji. Dodatkowo upewnij się, że DB_HOST wskazuje na używaną bazę danych, co jest szczególnie ważne w przypadku korzystania z kontenerów Docker.

Aby model mógł uczestniczyć w poszukiwaniach skautowych, konieczne jest: Aby wyraźnie oznaczyć go jako możliwy do przeszukiwania, dodaj cechę „Wyszukiwalny”Na przykład, jeśli masz model Pociąg, który reprezentuje tabelę pociągów z polem tytułu, możesz zdefiniować go w następujący sposób:

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

Metoda searchableAs pozwala dostosuj nazwę indeksu w wyszukiwarceZamiast używać domyślnej nazwy pochodzącej z modelu, Scout przejmuje kontrolę. Od tego momentu Scout zajmuje się synchronizacją operacji tworzenia, aktualizacji i usuwania z indeksem zdalnym lub lokalnym, w zależności od wybranego sterownika.

Laravel Scout z Algolią: błyskawiczne wyszukiwanie w SaaS

Algolia to usługa SaaS skoncentrowana na aby zapewnić bardzo szybkie i trafne przeszukiwanie dużych wolumenów danychPosiada panel internetowy do zarządzania indeksami, regułami trafności, synonimami itp. i bardzo dobrze integruje się z Laravel poprzez Scout i oficjalnego klienta PHP.

Aby używać Algolii ze Scout, musisz zainstalować jej klienta PHP za pomocą Composera, zarejestrować swoje dane uwierzytelniające w pliku .env (identyfikator aplikacji i klucz API administratora) i ustaw SCOUT_DRIVER=algolia aby polecić programowi Scout korzystanie z tego silnika. W panelu Algolia można uzyskać zarówno identyfikator aplikacji, jak i klucz administracyjny.

Po skonfigurowaniu środowiska możesz użyć takich metod, jak: Train::search('text')->paginate(6) bezpośrednio do kontrolerów w celu wykonywania wyszukiwań w polach indeksowanych i otrzymywania wyników w podzielonym na strony formacie Eloquent, gotowych do przekazania do widoku Blade.

Na przykładMożesz mieć kontroler wskaźnik która wyświetla wszystkie pociągi lub wykonuje wyszukiwanie, jeśli otrzymano parametr titlesearch, oraz metodę create służącą do wstawiania nowych pociągów do indeksu:

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

W odpowiednim widoku możesz łączyć formularz do rejestracji nowych pociągów i kolejny formularz GET z polem titlesearch, które uruchamia wyszukiwanie po przesłaniu. Następnie wystarczy przeiterować kolekcję pociągów i wyświetlić ich pola w tabeli, korzystając z linków paginacji generowanych przez Laravel.

Zwiad z Meilisearch, bazą danych i zbiorami

Jeśli wolisz unikać usług zewnętrznych, Meilisearch to wyszukiwarka o otwartym kodzie źródłowym które można wdrożyć lokalnie lub w ramach własnej infrastruktury. Scout integruje się z Meilisearch w bardzo podobny sposób jak Algolia, po prostu zmieniając sterownik i dodając zmienne MEILISEARCH_HOST i MEILISEARCH_KEY do pliku .env.

Aby z niego korzystać, należy zainstalować klienta PHP Meilisearch, dostosować SCOUT_DRIVER=meilisearch i wskaż zmienną MEILISEARCH_HOST na adres URL instancji (na przykład http://127.0.0.1:7700). Jeśli posiadasz już wcześniejsze rekordy, możesz je zindeksować poleceniem php artisan scout:import "App\Models\Train", aby wyszukiwarka miała je pod ręką.

W mniejszych lub średnich zastosowaniach możesz również wybrać Baza danych kierowców ScoutWykorzystuje to indeksy pełnotekstowe i polecenia LIKE w bazie danych MySQL lub PostgreSQL. W tym przypadku nie potrzebujesz usługi zewnętrznej; wystarczy ustawić parametr SCOUT_DRIVER=database, aby Scout używał samej bazy danych jako swojej wyszukiwarki.

Inną interesującą opcją jest kolekcja sterowników, która działa na kolekcjach Eloquent w pamięciTen silnik filtruje wyniki za pomocą klauzul WHERE i filtrowania kolekcji i jest kompatybilny z dowolną bazą danych obsługiwaną przez Laravel. Można go aktywować za pomocą `SCOUT_DRIVER=collection` lub dostosowując plik konfiguracyjny Scout, aby uzyskać bardziej szczegółowe ustawienia.

Integracja z Elasticsearch za pomocą Eksploratora

Jeśli Twoje potrzeby wyszukiwania obejmują praca z ogromnymi wolumenami danych i analizą w czasie rzeczywistymElasticsearch to klasyka. W ekosystemie Laravel nowoczesnym sposobem na jego integrację ze Scout jest użycie kontrolera Explorer, który działa jak pomost między modelami a klastrem Elasticsearch.

W tym celu zazwyczaj używa się Dockera wraz z rozbudowanym plikiem docker-compose, który oprócz typowych usług (Laravel, MySQL, Redis, Meilisearch itp.), Kontenery Elasticsearch i KibanaNastępnie należy zainstalować pakiet jeroen-g/explorer za pomocą Composera i opublikować jego plik konfiguracyjny, aby wskazać, które modele powinny zostać zindeksowane.

W pliku config/explorer.php możesz zarejestrować swoje modele pod kluczem indexes, na przykład dodając Aplikacja\Modele\Pociąg::classDodatkowo należy zmienić sterownik Scout na elastic w pliku .env za pomocą SCOUT_DRIVER=elastic, aby wszystko wskazywało na Elasticsearch.

W modelu Train należy zaimplementować interfejs Explored i zastąpić metodę. mapowalny jakoktóry definiuje mapę pól, które zostaną wysłane do indeksu. Minimalny przykład:

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

Od teraz, Możesz uruchamiać wyszukiwania w Elasticsearch przy użyciu tego samego interfejsu Scout., korzystając z bardzo krótkich czasów reakcji i pełnej mocy zapytań tego silnika, bez opuszczania ekosystemu Laravel.

Dzięki wszystkim tym podejściom — od podstawowego autouzupełniania z wykorzystaniem Fetch lub jQuery, przez filtrowanie front-endu z Alpine.js, po pełnotekstowe wyszukiwanie z wykorzystaniem Laravel Scout i różnych sterowników — Laravel oferuje Ci ogromną liczbę opcji wdrażania wyszukiwań w czasie rzeczywistym dostosowane do rozmiaru Twojego projektu, wydajności, której potrzebujesz, i infrastruktury, którą chcesz utrzymywać.

  Programowanie gier wideo: jak zacząć — przewodnik krok po kroku