Kumpletong gabay sa real-time na paghahanap sa Laravel

Huling pag-update: 5 Disyembre 2025
May-akda: TecnoDigital
  • Binibigyang-daan ka ng Laravel na ipatupad ang lahat mula sa mga simpleng search engine na may AJAX hanggang sa mga advanced na full-text na paghahanap gamit ang Laravel Scout at mga panlabas na search engine tulad ng Algolia, Meilisearch, o Elasticsearch.
  • Para sa magaan na paghahanap, ang pag-filter sa frontend gamit ang Alpine.js o gamit ang mga native na kahilingan sa pagkuha ay maiiwasan ang labis na karga sa server at pinapahusay ang karanasan ng user sa maliliit na listahan.
  • Isinasentro ng Laravel Scout ang pagsasama sa iba't ibang search engine at ginagawang madali na markahan ang mga modelo bilang mahahanap, pamahalaan ang mga index, at ilunsad ang mga query nang pantay-pantay.
  • Ang pagpili ng engine (SaaS, open source o database) ay dapat na nakabatay sa dami ng data, ang pagiging kumplikado ng mga paghahanap at ang pagganap at pagpapanatili ng mga kinakailangan ng proyekto.

real-time na paghahanap sa Laravel

Kapag nagsimula kang magtrabaho kasama ang Laravel at kailangan mo ng isang real-time na search engine na tumutugon kaagadMadaling mawala sa isang libong posibleng diskarte: AJAX na may fetch, jQuery, Alpine.js, Scout na may Algolia o Meilisearch, frontend filtering, atbp. Ang magandang balita ay ang Laravel ecosystem ay nagbibigay na ng halos lahat ng kailangan mo para mag-set up ng maayos at mabilis na paghahanap nang hindi namamatay sa pagsubok.

Sa artikulong ito makikita mo kung paano mag-assemble iba't ibang uri ng real-time na paghahanap sa LaravelMula sa classic na autocomplete ng AJAX hanggang sa mga full-text na paghahanap gamit ang Laravel Scout at mga search engine tulad ng Algolia, Meilisearch, ang database mismo, o maging ang Elasticsearch. Makakakita ka rin ng mga magaan na alternatibo sa Alpine.js para sa direktang pag-filter ng data sa browser kapag maliit ang dami ng data.

Ano ang isang real-time na paghahanap sa Laravel at paano gumagana ang mga pangunahing kaalaman?

Ang ideya sa likod ng isang real-time na paghahanap ay na, habang nagta-type ang user sa isang text fieldNati-trigger ang isang query at ina-update ang mga resulta nang hindi nire-reload ang page. Sa teknikal, kinabibilangan ito ng tatlong pangunahing bahagi: ang backend ng Laravel, JavaScript ng browser, at ang pagpapalitan ng data sa format na JSON.

Sa isang banda, Ang Laravel ay gumaganap bilang layer ng server Responsable ito para sa pagtanggap ng mga kahilingan, pagbibigay-kahulugan sa mga parameter ng paghahanap (ang ipinasok na teksto), pag-query sa database, at pagbabalik ng isang structured na tugon, kadalasan sa JSON na format. Ang tugon na ito ay maaaring magpahiwatig ng tagumpay, pagkakamali, o walang nakitang mga resulta.

Sa kabilang dulo, Responsable ang JavaScript sa pakikinig sa mga kaganapan ng user. Sa input ng paghahanap, magpadala ng mga asynchronous na kahilingan (AJAX) sa backend at ipakita ang ibinalik na data sa page nang hindi nagsasagawa ng ganap na pag-refresh ang browser. Magagawa ito gamit ang native fetch, jQuery AJAX, o maliliit na reaktibong library tulad ng Alpine.js.

Gamit ang pangunahing mekanismong ito maaari kang bumuo mula sa a Simpleng autocomplete na may ilang record, hanggang sa isang advanced na full-text na search engine na may kaugnayan, pagination at mga filter, na sinusuportahan ng mga aklatan tulad ng Laravel Scout at mga panlabas na search engine na na-optimize para sa paghahanap.

Modelo, ruta, at controller para sa isang pangunahing real-time na search engine

Bago ka magsaliksik sa JavaScript, kailangan mong tiyakin na ang panig ng Laravel ay maayos na nakaayos: isang Eloquent na modelo na hahanapin, i-clear ang mga ruta, at isang dedikadong controller upang pamahalaan ang lohika ng paghahanap sa real time.

Ang unang hakbang ay ang pagkakaroon ng Eloquent na modelo na kumakatawan sa talahanayan kung saan ka maghahanap. Isipin ang isang talahanayan ng mga bansa at isang modelo na tinatawag Bansa Napakasimple, walang timestamp at pinapayagan ang maramihang pagtatalaga:

Halimbawa ng isang minimal na Eloquent na modelo para sa mga paghahanap:

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

Ito ay ipinahiwatig dito na ang modelo Matatagpuan ang Pais sa karaniwang namespace ng LaravelNagmana ito mula sa Model at nagbibigay-daan sa iyong magtalaga ng anumang field na may create() sa pamamagitan ng pag-iwan sa binabantayang array na walang laman. Sa pamamagitan ng hindi pagpapagana ng mga timestamp na may pampublikong $timestamps = false, maiiwasan mo ang mga problema kung ang talahanayan ay walang mga column na created_at at updated_at.

Ang susunod na hakbang ay upang tukuyin ang mga ruta na hahawak sa parehong pagpapakita ng search engine at mga kahilingan ng AJAXPinagsasama ng isang napaka-karaniwang pamamaraan ang isang GET na ruta upang ipakita ang view at isang POST na ruta na idinisenyo upang makatanggap ng mga real-time na query:

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

Ang root route ay nagbabalik ng welcome view, habang ang URL Ang /search ay nakalaan para sa paggana ng paghahanapIpinapakita ng paraan ng index() ng controller ang form at input ng paghahanap, habang ang paraan ng paghahanap() ay nagpoproseso ng mga asynchronous na kahilingan na ipinadala mula sa browser.

Sa controller maaari kang magpatupad ng isang napaka-praktikal na pattern: Maghanda ng default na array ng tugon kung sakaling magkaroon ng error at i-overwrite lamang ito kapag ito ay tunay na isang wastong kahilingan ng AJAX at ang query ay isinasagawa nang walang mga problema.

Ang controller ay maaaring magkaroon ng a katulad na istraktura ito:

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

Sa puntong ito mayroon ka na ang kumpletong ikot ng backend: papasok na kahilingan ng AJAX, pagsuri na ito ay AJAX, pagtatanong kung saan gusto at nililimitahan ang mga resulta sa isang makatwirang numero gamit ang take(10) upang maiwasan ang labis na karga ng database. Ang tugon ay palaging ipinapadala sa JSON, na lubos na nagpapasimple sa gawain ng frontend.

Blade view at JavaScript fetch para sa reaktibong paghahanap

Kapag handa na ang modelo, ruta, at controller, oras na para buuin ang nakikitang bahagi: isang form na may field ng paghahanap at isang bloke upang ipakita ang mga resulta, kasama ang JavaScript na responsable sa paggawa ng mga kahilingan sa background.

Ang Blade view ay maaaring maging napaka-simple, umaasa sa CSRF token na ini-inject ng Laravel upang patunayan ang mga kahilingan sa POST at sa isang input ng paghahanap na madaling gamitin:

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

Sa halimbawang ito ang script Makinig para sa kaganapan ng keyup sa input ng paghahanapAng bawat keystroke ay nagpapalitaw ng kahilingan sa pagkuha sa /search path. Ang kasalukuyang text ng field ay ipinadala sa JSON na format, at ang mga pangunahing header tulad ng X-Requested-With ay kasama upang isaad na ito ay AJAX, kasama ang CSRF token upang i-bypass ang native na proteksyon ng Laravel.

Kapag dumating ang tugon, binago ito sa JSON at dynamic na nabuo. isang maliit na listahan ng HTML na may mga resultao isang mensahe tulad ng "Walang nakitang mga resulta" kapag walang ibinalik na data ang query. Lahat ng ito nang hindi nire-reload ang page, sa natural na paraan para sa user.

Ang pattern na ito ay maaaring higit pang pinuhin gamit ang maliliit na detalye ng UX, tulad ng pagdaragdag ng a antala (debounce) sa pagitan ng mga keystroke, magpakita ng loader o pangasiwaan ang mga error sa network upang maiwasang magmukhang frozen ang interface kapag may nabigo.

Live na paghahanap sa Laravel at AJAX gamit ang jQuery

Kahit na ang fetch ay nakakuha ng maraming lupa ngayon, Ang jQuery AJAX ay nananatiling napakapopular sa mga legacy project o sa mga team na naipatupad na ito. Ang ideya ay eksaktong pareho: kunin kung ano ang mga uri ng user, gumawa ng asynchronous na kahilingan, at i-refresh ang DOM.

Ang karaniwang daloy ng trabaho na may jQuery sa Laravel para sa live na paghahanap ay karaniwang kasama ang mga pangunahing hakbang na ito: tukuyin ang isang partikular na ruta, lumikha ng nakalaang controller, buuin ang Blade view gamit ang input ng paghahanap At sa wakas, idagdag ang jQuery code na nagpapalitaw sa AJAX habang ito ay nai-type.

Ang proseso ay gumagana tulad nito: kapag ang user ay nagsimulang mag-type, Nagpapadala ang jQuery ng query sa server gamit ang string ng paghahanap. Sinasala ng Laravel ang impormasyon sa database, nagbabalik ng JSON na may mga katugmang resulta, at ang jQuery ay nag-a-update ng HTML na lalagyan sa page upang ipakita ang mga tugma, lahat sa loob ng millisecond.

Ang bentahe ng paggamit ng jQuery ay iyon Ito ay medyo nagbubuod sa syntax ng AJAX At napakadirektang basahin kung mayroon ka nang library sa iyong proyekto. Gayunpaman, nagdaragdag ka ng karagdagang dependency na maaaring hindi kinakailangan kung magagawa mo ang modernong JavaScript at native fetch.

Real-time na pag-filter at paghahanap sa frontend gamit ang Alpine.js

Kapag medyo maliit ang data na ipapakita (halimbawa, mas mababa sa 50 item), hindi palaging sulit ang pag-set up ng backend na may mga kumplikadong paghahanap. Sa mga kasong iyon, ang isang napaka-maginhawang opsyon ay Direktang mag-filter sa browser gamit ang Alpine.js, nang hindi gumagawa ng mga kahilingan sa server habang nagta-type ang user.

Ang ideya ay paunang kalkulahin ang isang string ng paghahanap para sa bawat elemento (halimbawa, pangalan, paglalarawan, at kategorya sa maliliit na titik), iimbak ito sa isang katangian ng data-search-text, at hayaan ang Alpine.js na pangasiwaan ang iba. ipakita o itago ang mga elemento ayon sa nakasulat na teksto sa isang field ng paghahanap.

Ang bahagi ng Alpine.js ay maaaring magkaroon ng istraktura na katulad nito: 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;
},
}

Sa view, ang bawat card o row ng data ay magdadala ng attribute data-search-text na may tekstong inihanda na sa maliit na titikSamakatuwid, ang filter ay binawasan sa isang includes() function sa JavaScript, na napakabilis para sa mga maikling listahan:

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

Bilang karagdagan, maaari kang magpakita ng walang laman na bloke ng estado kapag Walang mga resulta para sa kasalukuyang termino para sa paghahanap.pag-iimbita sa user na baguhin ang text o i-clear ang field gamit ang isang button na nagre-reset lang sa paghahanap sa isang walang laman na string.

Ang pamamaraang ito ay may malinaw na mga pakinabang: Walang mga tawag sa server sa panahon ng paghahanap.Ang pakikipag-ugnayan ay halos madalian, at ang lohika ay nananatiling lubos na lokal at madaling i-debug. Ito ay perpekto para sa mabilis na mga tagapili, mga modal ng pagpili ng item, o maliliit na katalogo na naka-embed sa isang pahina ng Laravel.

Laravel Scout: Full-text na paghahanap gamit ang mga espesyal na makina

Kapag naging seryoso ang mga bagay at kailangan mo mabilis, may-katuturan, at nasusukat na full-text na mga paghahanapAng natural na landas sa Laravel ay Laravel Scout. Ang Scout ay isang integration layer na nagbibigay-daan sa iyong madaling ikonekta ang iyong Eloquent na mga modelo sa mga search engine tulad ng Algolia, Meilisearch, sarili mong database, in-memory na mga koleksyon, o kahit Elasticsearch sa pamamagitan ng mga external na controller.

Upang makapagsimula sa Scout, ang karaniwang bagay ay lumikha ng isang bagong proyekto ng Laravel o muling gumamit ng isang umiiral naUpang ilunsad ito, gamitin ang Docker (halimbawa, kasama ang Laravel Sail) at pagkatapos ay i-install ang library gamit ang Composer. Kapag tapos na iyon, i-publish ang scout.php configuration file at ayusin ang mga variable ng kapaligiran ayon sa driver na gusto mong gamitin.

Ang karaniwang daloy ng trabaho ay ang pag-install ng Scout kasama ang Composer, pag-publish ng configuration nito, at i-activate ang indexing queue gamit ang SCOUT_QUEUE=true Sa .env file, tiyaking ang mga operasyong masinsinang mapagkukunan ay pinoproseso sa background, na nagpapahusay sa mga oras ng pagtugon sa application. Bukod pa rito, dapat mong tiyakin na ang DB_HOST ay tumuturo sa database na iyong ginagamit, na lalong mahalaga kung gumagamit ka ng mga lalagyan ng Docker.

Upang makalahok ang isang modelo sa mga paghahanap sa Scout, kinakailangan na Upang tahasan itong markahan bilang nahahanap sa pamamagitan ng pagdaragdag ng Naghahanap na katangianHalimbawa, kung mayroon kang modelo ng Tren na kumakatawan sa isang talahanayan ng mga tren na may field ng pamagat, maaari mo itong tukuyin tulad nito:

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

Pinapayagan ng searchableAs na paraan i-customize ang pangalan ng index sa search engineSa halip na gamitin ang default na pangalan na nagmula sa modelo, ang Scout ang pumalit. Mula rito, pinangangasiwaan ng Scout ang pag-synchronize ng mga operasyon sa paggawa, pag-update, at pagtanggal sa remote o lokal na index, depende sa napiling driver.

Laravel Scout with Algolia: SaaS Search na napakabilis ng kidlat

Ang Algolia ay isang serbisyo ng SaaS na nakatuon sa upang mag-alok ng napakabilis at nauugnay na mga paghahanap sa malalaking dami ng dataMayroon itong web panel para sa pamamahala ng mga index, mga tuntunin sa kaugnayan, kasingkahulugan, atbp., at napakahusay na pinagsama sa Laravel sa pamamagitan ng Scout at ang opisyal na kliyente ng PHP.

Upang magamit ang Algolia sa Scout, kakailanganin mong i-install ang PHP client nito sa Composer, irehistro ang iyong mga kredensyal sa .env file (Application ID at Admin API Key), at itakda ang SCOUT_DRIVER=algolia para sabihin sa Scout na gamitin ang makinang ito. Mula sa panel ng Algolia maaari mong makuha ang parehong application ID at ang administrative key.

Kapag na-configure na ang kapaligiran, maaari kang gumamit ng mga pamamaraan tulad ng Train::search('text')->paginate(6) direkta sa iyong mga controllers upang magsagawa ng mga paghahanap sa mga naka-index na field, na tumatanggap ng mga resulta sa paginated Eloquent na format na handa nang ipasa sa isang Blade view.

HalimbawaMaaari kang magkaroon ng controller index na naglilista ng lahat ng mga tren o nagsasagawa ng paghahanap kung ang isang titlesearch parameter ay natanggap, at isang paraan ng paggawa upang magpasok ng mga bagong tren sa index:

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

Sa kaukulang view, maaari mong pagsamahin isang form para sa pagpaparehistro ng mga bagong tren at isa pang GET form na may isang titlesearch field na nagti-trigger ng paghahanap kapag naisumite. Pagkatapos ay kailangan mo lamang na umulit sa koleksyon ng mga tren at ipakita ang kanilang mga field sa isang talahanayan, sinasamantala ang mga link ng pagination na nabuo ng Laravel.

Scout na may Meilisearch, database at mga koleksyon

Kung mas gusto mong iwasan ang mga panlabas na serbisyo, Ang Meilisearch ay isang open source na search engine na maaari mong i-deploy nang lokal o sa iyong imprastraktura. Sumasama ang Scout sa Meilisearch sa isang katulad na paraan sa Algolia, sa pamamagitan lamang ng pagpapalit ng driver at pagdaragdag ng MEILISEARCH_HOST at MEILISEARCH_KEY na mga variable sa .env file.

Upang magamit ito, i-install mo ang Meilisearch PHP client, ayusin SCOUT_DRIVER=meilisearch at ituro ang MEILISEARCH_HOST sa instance URL (halimbawa, http://127.0.0.1:7700). Kung mayroon ka nang mga naunang tala, maaari mong i-index ang mga ito gamit ang command na php artisan scout:import "App\Models\Train" upang ang makina ay magkaroon ng mga ito na magagamit.

Sa mas maliit o katamtamang mga application, maaari mo ring piliin ang Database ng driver ng ScoutGinagamit nito ang mga full-text index at LIKE command sa iyong MySQL o PostgreSQL database. Sa kasong ito, hindi mo kailangan ng panlabas na serbisyo; itakda lamang ang SCOUT_DRIVER=database para sa Scout na gamitin ang database mismo bilang search engine nito.

Ang isa pang kagiliw-giliw na pagpipilian ay ang koleksyon ng driver, na gumagana sa Eloquent na mga koleksyon sa memoryaSinasala ng engine na ito ang mga resulta gamit ang mga sugnay na WHERE at pag-filter ng koleksyon, at tugma sa anumang database na sinusuportahan ng Laravel. Maaari mo itong i-activate gamit ang `SCOUT_DRIVER=collection` o sa pamamagitan ng pagsasaayos ng configuration file ng Scout para sa mas tiyak na mga setting.

Pagsasama sa Elasticsearch gamit ang Explorer

Kung may kinalaman ang iyong paghahanap nagtatrabaho sa malaking dami ng data at real-time na pagsusuriAng Elasticsearch ay isang klasiko. Sa Laravel ecosystem, isang modernong paraan upang maisama ito sa Scout ay ang paggamit ng Explorer controller, na nagsisilbing tulay sa pagitan ng iyong mga modelo at isang Elasticsearch cluster.

Upang gawin ito, karaniwang ginagamit ang Docker, kasama ang isang rich docker-compose file na, bilang karagdagan sa mga karaniwang serbisyo (Laravel, MySQL, Redis, Meilisearch, atbp.), Mga lalagyan ng Elasticsearch at KibanaPagkatapos ay i-install mo ang jeroen-g/explorer package sa pamamagitan ng Composer at i-publish ang configuration file nito upang isaad kung aling mga modelo ang dapat ma-index.

Sa config/explorer.php file maaari mong irehistro ang iyong mga modelo sa ilalim ng index ng key, halimbawa sa pamamagitan ng pagdaragdag App\Models\Train::classBukod pa rito, binago mo ang Scout driver sa elastic sa .env file na may SCOUT_DRIVER=elastic upang ang lahat ay tumuturo sa Elasticsearch.

Sa loob ng modelo ng Train, dapat ipatupad ang Explored interface at ma-override ang paraan. mappableAsna tumutukoy sa mapa ng mga field na ipapadala sa index. Ang isang minimal na halimbawa ay:

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

Simula ngayon, Maaari kang maglunsad ng mga paghahanap sa Elasticsearch gamit ang parehong interface ng Scout., nakikinabang mula sa napakababang oras ng pagtugon at ang buong lakas ng query ng engine na ito, ngunit hindi umaalis sa Laravel ecosystem.

Sa lahat ng approach na ito—mula sa basic autocomplete na may fetch o jQuery, hanggang sa frontend na pag-filter gamit ang Alpine.js, hanggang sa full-text na paghahanap gamit ang Laravel Scout at iba't ibang driver— Binibigyan ka ng Laravel ng malaking hanay ng mga opsyon para sa pagpapatupad ng mga real-time na paghahanap na angkop sa laki ng iyong proyekto, ang pagganap na kailangan mo, at ang imprastraktura na handa mong panatilihin.

  Video Game Programming: Paano Magsisimula - Step-by-Step na Gabay