- A Laravel lehetővé teszi, hogy mindent megvalósíts az egyszerű AJAX-os keresőmotoroktól kezdve a fejlett teljes szöveges keresésekig a Laravel Scout és külső keresőmotorok, például az Algolia, a Meilisearch vagy az Elasticsearch használatával.
- Könnyű keresések esetén az Alpine.js-sel vagy natív lekérési kérésekkel történő szűrés a frontenden elkerüli a szerver túlterhelését, és javítja a felhasználói élményt kis listák esetén.
- A Laravel Scout központosítja a különböző keresőmotorokkal való integrációt, és megkönnyíti a modellek kereshetőként való megjelölését, az indexek kezelését és a lekérdezések egységes indítását.
- A motor (SaaS, nyílt forráskódú vagy adatbázis) kiválasztásának az adatmennyiségen, a keresések összetettségén, valamint a projekt teljesítmény- és karbantartási követelményein kell alapulnia.

Amikor elkezdesz Laravel-lel dolgozni, és szükséged van egy valós idejű keresőmotorra, amely azonnal reagál , könnyű elveszni az ezernyi lehetséges megközelítés között: AJAX fetch-kel, jQuery, Alpine.js, Scout Algoliával vagy Meilisearch-kel, frontend szűrés stb. A jó hír az, hogy a Laravel ökoszisztéma már gyakorlatilag mindent biztosít, amire szükséged van egy zökkenőmentes és gyors keresőmotor felépítéséhez anélkül, hogy túlterhelt lennél.
Ebben a cikkben megtudhatod, hogyan valósíthatsz meg különböző típusú valós idejű kereséseket Laravelben , a klasszikus AJAX automatikus kiegészítéstől a teljes szöveges keresésekig a Laravel Scout és olyan keresőmotorok használatával, mint az Algolia, a Meilisearch, maga az adatbázis vagy akár az Elasticsearch. Emellett felfedezheted az Alpine.js könnyűsúlyú alternatíváit is az adatok böngészőben történő szűrésére kis adathalmazok kezelésekor.
Mi a valós idejű keresés Laravelben, és hogyan működnek az alapok?
A valós idejű keresés mögött az az elképzelés áll, hogy amint a felhasználó beír egy szövegmezőbe , egy lekérdezés indul el, és az eredmények frissülnek az oldal újratöltése nélkül. Technikailag ez három kulcsfontosságú összetevőt foglal magában: a Laravel backendet, a böngésző JavaScriptjét és a JSON formátumú adatcserét.
Egyrészt a Laravel szerverrétegként működik, amely felelős a kérések fogadásáért, a keresési paraméterek (a beírt szöveg) értelmezéséért, az adatbázis lekérdezéséért és egy strukturált válasz visszaadásáért, általában JSON formátumban. Ez a válasz jelezheti a sikert, a hibát, vagy azt, hogy nem található találat.
A másik oldalon a JavaScript kezeli a felhasználói események figyelését a keresési bemeneten, aszinkron kéréseket (AJAX) küld a háttérrendszernek, és a visszaadott adatokat megjeleníti az oldalon anélkül, hogy teljes böngészőfrissítést igényelne. Ez megtehető natív lehívással, jQuery AJAX-szal vagy kis reaktív könyvtárakkal, mint például az Alpine.js.
Ezzel az alapvető mechanizmussal bármit felépíthetsz az egyszerű, néhány rekorddal rendelkező automatikus kiegészítéstől kezdve a fejlett, teljes szöveges keresőmotorig, relevanciával, oldalszámozással és szűrőkkel, olyan könyvtárakra támaszkodva, mint a Laravel Scout és a keresésekre optimalizált külső keresőmotorok.
Modell, útvonalak és vezérlő egy alapvető valós idejű keresőmotorhoz
Mielőtt belemerülnél a JavaScriptbe, a Laravel oldalának jól szervezettnek kell lennie: egy Eloquent modellnek a kereséshez, egyértelmű útvonalaknak és egy vezérlőnek, amely valós időben kezeli a keresési logikát.
Az első lépés egy Eloquent modell létrehozása, amely azt a táblázatot reprezentálja, amelyben keresni fogsz. Képzelj el egy országokat tartalmazó táblázatot és egy nagyon egyszerű modellt, az Országot , időbélyegek nélkül és tömeges hozzárendeléssel:
Példa egy minimális Eloquent modellre keresésekhez :
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;
}
Ez azt jelzi, hogy a Pais modell a standard Laravel névtérben található , a Model-től örököl, és lehetővé teszi bármely mező hozzárendelését a create() függvénnyel a védett tömb üresen hagyásával. Az időbélyegek letiltásával a public $timestamps = false paraméterrel elkerülhetők a problémák, ha a táblázat nem tartalmazza a created_at és az updated_at oszlopokat.
A következő lépés az útvonalak meghatározása , amelyek mind a keresőmotor megjelenítését, mind az AJAX kéréseket kezelik . Egy nagyon gyakori séma egy GET útvonalat kombinál a nézet megjelenítéséhez és egy POST útvonalat, amely a lekérdezések valós idejű fogadására szolgál:
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 gyökérútvonal egy üdvözlő nézetet ad vissza, míg a /search URL a keresési funkciók számára van fenntartva . A vezérlő index() metódusa megjeleníti az űrlapot és a keresési bemenetet, míg a search() metódus a böngészőből küldött aszinkron kéréseket dolgozza fel.
A vezérlőben egy nagyon praktikus mintát lehet megvalósítani: készítsünk egy alapértelmezett válasz tömböt hiba esetére , és csak akkor írjuk felül, ha valóban érvényes AJAX kérésről van szó, és a lekérdezés problémamentesen végrehajtódik.
A vezérlő felépítése hasonló lehet :
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);
}
}
Ezen a ponton a teljes backend ciklus következik : bejövő AJAX kérés, annak ellenőrzése, hogy valóban AJAX kérés-e, lekérdezés a `where like` használatával, és az eredmények számának ésszerű értékre korlátozása a `take(10)` használatával az adatbázis túlterhelésének elkerülése érdekében. A válasz mindig JSON-ban kerül elküldésre, ami nagyban leegyszerűsíti a frontend munkáját.
Blade nézet és JavaScript lekérés reaktív kereséshez
Miután a modell, az útvonalak és a vezérlő elkészült, itt az ideje felépíteni a látható részt: egy űrlapot egy keresőmezővel és egy blokkal az eredmények megjelenítéséhez , valamint a JavaScriptet, amely a háttérben a kérések végrehajtásáért felelős.
A Blade nézet nagyon egyszerű lehet, a Laravel által a POST kérések validálásához befecskendezett CSRF tokenre és egy kényelmesen használható keresési bemenetre támaszkodik:
<!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>
Ebben a példában a szkript a search bemeneten található keyup eseményre figyel , így minden billentyűleütés egy lekérési kérést indít el a /search elérési útra. A mező aktuális szövege JSON formátumban kerül elküldésre, és kulcsfejlécek, például az X-Requested-With szerepelnek annak jelzésére, hogy AJAX-ról van szó, valamint a CSRF token a Laravel natív védelmének megkerülésére.
Amikor a válasz megérkezik, JSON formátumba konvertálódik, és dinamikusan generálódik egy kis HTML lista az eredményekkel , vagy egy üzenet, például a „Nincs találat” jelenik meg, ha a lekérdezés nem ad vissza adatot. Mindez az oldal újratöltése nélkül, a felhasználó számára természetes módon történik.
Ez a minta tovább finomítható apró UX részletekkel, például billentyűleütések közötti pattogás csökkentésével , betöltő megjelenítésével vagy hálózati hibák kezelésével, hogy megakadályozzuk a felület lefagyását hiba esetén.
Élő keresés Laravel és AJAX segítségével jQuery használatával
Bár a fetch jelentős teret kapott, a jQuery AJAX továbbra is nagyon népszerű a hagyományos projektekben vagy csapatokban, amelyek már integrálták. Az ötlet pontosan ugyanaz: rögzíteni a felhasználó által beírt adatokat, aszinkron kérést kezdeményezni, és frissíteni a DOM-ot.
Egy tipikus jQuery munkafolyamat Laravelben élő kereséshez általában a következő alapvető lépéseket tartalmazza: egy adott útvonal definiálása, egy dedikált vezérlő létrehozása, a Blade nézet felépítése a keresési bemenettel , és végül a jQuery kód hozzáadása, amely elindítja az AJAX-ot gépelés közben.
A folyamat a következőképpen működik: amikor a felhasználó elkezd gépelni, a jQuery egy lekérdezést küld a szervernek a keresési karakterlánccal. A Laravel kiszűri az adatbázisban található információkat, visszaad egy JSON objektumot a találatokkal, és a jQuery frissíti az oldalon található HTML konténert, hogy az tükrözze a találatokat, mindezt ezredmásodpercek alatt.
A jQuery használatának előnye, hogy jelentősen leegyszerűsíti az AJAX szintaxist , és nagyon könnyen olvasható, ha már megvan a könyvtár a projektedben. Azonban egy további függőséget vezet be, amelyre esetleg nincs szükség, ha tudsz dolgozni a modern JavaScriptdel és a natív lehívási funkciókkal.
Valós idejű szűrés és keresés a frontendben az Alpine.js segítségével
Amikor a megjelenítendő adatmennyiség viszonylag kicsi (például kevesebb, mint 50 elem ), nem mindig érdemes összetett kereséseket végző backend rendszert beállítani. Ilyen esetekben egy nagyon kényelmes lehetőség a böngészőben közvetlenül az Alpine.js használatával történő szűrés , anélkül, hogy kéréseket küldenénk a szervernek, miközben a felhasználó gépel.
Az ötlet az, hogy minden elemhez előre kiszámítunk egy keresési karakterláncot (pl. név, leírás és kategória kisbetűkkel), elmentjük egy data-search-text attribútumban, és hagyjuk, hogy az Alpine.js kezelje az elemek megjelenítését vagy elrejtését a keresőmezőbe beírt szöveg alapján .
Az Alpine.js komponensnek ehhez hasonló struktúrája lehet: 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;
},
}
A nézetben minden kártya vagy adatsor rendelkezne egy data-search-text attribútummal, amelynek a szövege már kisbetűs , így a szűrő egy included() metódusra redukálódik JavaScriptben, ami nagyon gyors a rövid listák esetében:
<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>
Ezenkívül üres állapotblokkot is megjeleníthet, ha az aktuális keresési kifejezésre nincs találat , így a felhasználó módosíthatja a szöveget vagy törölheti a mezőt egy gombbal, amely egyszerűen visszaállítja a keresést egy üres karakterláncra.
Ennek a megközelítésnek egyértelmű előnyei vannak: nincsenek szerverhívások a keresés során , az interakció gyakorlatilag azonnali, a logika pedig továbbra is nagyon lokális és könnyen hibakereshető. Tökéletes gyors szelektorokhoz, elemkiválasztó modális ablakokhoz vagy Laravel oldalba ágyazott kis katalógusokhoz.
Laravel Scout: Teljes szöveges keresés speciális motorokkal
Amikor a dolgok komolyra fordulnak, és gyors, releváns és skálázható teljes szöveges keresésre van szükség , a Laravelben a természetes megoldás a Laravel Scout. A Scout egy integrációs réteg, amely lehetővé teszi az Eloquent modellek egyszerű összekapcsolását olyan keresőmotorokkal, mint az Algolia, a Meilisearch, az adatbázisoddal, a memóriában tárolt gyűjteményekkel vagy akár az Elasticsearch-kel külső vezérlőkön keresztül.
A Scout használatának megkezdéséhez a szokásos megközelítés egy új Laravel projekt létrehozása vagy egy meglévő újrafelhasználása , annak elindítása Dockerrel (például Laravel Sail használatával), majd a függvénykönyvtár telepítése Composerrel. Ha ez megtörtént, közzé kell tenni a scout.php konfigurációs fájlt, és a használni kívánt illesztőprogramnak megfelelően kell módosítani a környezeti változókat.
Egy tipikus munkafolyamat a Scout telepítése a Composerrel, a konfiguráció közzététele, és az indexelési sor engedélyezése a `.env` fájlban a `SCOUT_QUEUE=true` paraméterrel, hogy az erőforrás-igényes műveletek a háttérben feldolgozásra kerüljenek, javítva az alkalmazások válaszidejét. Ezenkívül ügyeljen arra is, hogy a `DB_HOST` a használt adatbázisra mutasson, ami különösen fontos, ha Docker konténereket használ.
Ahhoz, hogy egy modell részt vehessen a Scout keresésekben, explicit módon kereshetőként kell megjelölni a „Kereshető” tulajdonság hozzáadásával . Például, ha van egy „Vonat” modellje, amely egy „cím” mezővel rendelkező vonatok táblázatát ábrázolja, akkor így definiálhatja:
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';
}
}
A `searchableAs` metódus lehetővé teszi az index nevének testreszabását a keresőmotorban a modellből származó alapértelmezett név használata helyett. Innentől kezdve a Scout kezeli a létrehozási, frissítési és törlési műveletek szinkronizálását a távoli vagy a helyi indexszel, a kiválasztott illesztőprogramtól függően.
Laravel Scout az Algoliával: Villámgyors SaaS keresés
Az Algolia egy SaaS szolgáltatás, amely nagy mennyiségű adaton belüli nagyon gyors és releváns keresések biztosítására összpontosít . Webes panellel rendelkezik az indexek, relevanciaszabályok, szinonimák és egyebek kezeléséhez, és zökkenőmentesen integrálódik a Laravel-lel a Scout és a hivatalos PHP kliensen keresztül.
Az Algolia Scouttal való használatához telepítenie kell a PHP klienst a Composer segítségével, regisztrálnia kell a hitelesítő adatait az .env fájlban (alkalmazásazonosító és rendszergazdai API-kulcs), és konfigurálnia kell a SCOUT_DRIVER=algolia paramétert , hogy a Scout ezt a motort használja. Az alkalmazásazonosítót és az adminisztrátori kulcsot is lekérheti az Algolia irányítópultjáról.
Miután a környezet be van állítva, közvetlenül a vezérlőkben használhatsz olyan metódusokat, mint a Train::search('text')->paginate(6), hogy kereséseket végezz az indexelt mezőkön, és az eredményeket lapozott Eloquent formátumban kapod meg, amely készen áll a Blade nézetbe való átadásra.
Például lehet egy indexvezérlőd , amely listázza az összes vonatot, vagy keresést hajt végre, ha egy titlesearch paramétert adsz át, és egy create metódusod, amely új vonatokat szúr be az indexbe:
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();
}
A megfelelő nézetben kombinálhatsz egy űrlapot új vonatok hozzáadására és egy másik GET űrlapot egy címkereső mezővel, amely a beküldéskor elindítja a keresést. Ezután egyszerűen végighaladhatsz a vonatok gyűjteményén, és megjelenítheted a mezőiket egy táblázatban, kihasználva a Laravel által generált lapozási hivatkozásokat.
Felderítés a Meilisearch, adatbázis és gyűjtemények segítségével
Ha inkább elkerülnéd a külső szolgáltatásokat, a Meilisearch egy nyílt forráskódú keresőmotor , amelyet helyben vagy a saját infrastruktúrádon is telepíthetsz. A Scout az Algoliához nagyon hasonló módon integrálódik a Meilisearch-kel, egyszerűen a meghajtóprogram módosításával és a MEILISEARCH_HOST és MEILISEARCH_KEY változók hozzáadásával az .env fájlhoz.
A használatához telepítsd a Meilisearch PHP klienst, állítsd be a SCOUT_DRIVER=meilisearch értéket , és irányítsd a MEILISEARCH_HOST értékét a példány URL-címére (például http://127.0.0.1:7700). Ha már vannak rekordjaid, indexelheted őket a php artisan scout:import "App\Models\Train" paranccsal, hogy a motor elérhetővé tegye őket.
Kisebb vagy közepes méretű alkalmazásokhoz választhatod a Scout adatbázis-illesztőprogramját is , amely teljes szöveges indexeket és LIKE utasításokat használ a MySQL vagy PostgreSQL adatbázisodon. Ebben az esetben nincs szükséged külső szolgáltatásra; egyszerűen állítsd be a SCOUT_DRIVER=database értéket, hogy a Scout magát az adatbázist használja keresőmotorként.
Egy másik érdekes lehetőség a gyűjteményillesztő, amely memórián belüli Eloquent gyűjteményekkel működik . Ez a motor `where` és gyűjteményszűrési metódusok segítségével szűri az eredményeket, és kompatibilis a Laravel által támogatott bármely adatbázissal. Aktiválható a `SCOUT_DRIVER=collection` paraméterrel, vagy a Scout konfigurációs fájl módosításával, ha valami konkrétabbra van szüksége.
Elasticsearch integráció az Explorer használatával
Ha a keresési igényeid hatalmas adatmennyiséggel és valós idejű elemzéssel járnak , az Elasticsearch egy klasszikus. A Laravel ökoszisztémában a Scouttal való integráció modern módja az Explorer vezérlő használata, amely hidat képez a modelljeid és egy Elasticsearch klaszter között.
Ez jellemzően a Docker és egy gazdag docker-compose fájl használatát jelenti, amely a szokásos szolgáltatások (Laravel, MySQL, Redis, Meilisearch stb.) mellett az Elasticsearch és a Kibana konténerek mellett elindul . Ezután telepíted a jeroen-g/explorer csomagot a Composeren keresztül, és közzéteszed a konfigurációs fájlját, hogy megadd, mely modelleket kell indexelni.
A config/explorer.php fájlban regisztrálhatod a modelleidet az indexes kulcs alatt, például az App\Models\Train::class hozzáadásával . Ezenkívül a .env fájlban a Scout illesztőprogramot Elasticsearch-re kell állítani a SCOUT_DRIVER=elastic beállítással, hogy minden az Elasticsearch-re mutasson.
A Train modellen belül meg kell valósítani az Explored interfészt, és felül kell írni a mappableAs metódust , amely meghatározza az indexbe küldendő mezők leképezését. Egy minimális példa erre:
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,
];
}
}
Innen indíthatsz kereséseket az Elasticsearch-en ugyanazzal a Scout felülettel , kihasználva a nagyon alacsony válaszidőket és a motor teljes lekérdezési erejét, anélkül, hogy elhagynád a Laravel ökoszisztémát.
Mindezen megközelítésekkel – az alapvető automatikus kiegészítéstől a fetch vagy jQuery segítségével, az Alpine.js-sel végzett frontend szűrésen át a Laravel Scouttal és különféle illesztőprogramokkal végzett teljes szöveges keresésekig – a Laravel hatalmas választékot kínál valós idejű keresések megvalósításához, amelyek a projekt méretéhez, a szükséges teljesítményhez és a fenntartani kívánt infrastruktúrához igazodnak.