- Laravel membolehkan anda melaksanakan segala-galanya daripada enjin carian mudah dengan AJAX kepada carian teks penuh lanjutan menggunakan Laravel Scout dan enjin carian luaran seperti Algolia, Meilisearch atau Elasticsearch.
- Untuk carian yang ringan, menapis pada bahagian hadapan dengan Alpine.js atau dengan permintaan pengambilan asli mengelakkan lebihan beban pelayan dan meningkatkan pengalaman pengguna dalam senarai kecil.
- Laravel Scout memusatkan penyepaduan dengan enjin carian yang berbeza dan memudahkan untuk menandakan model sebagai boleh dicari, mengurus indeks dan melancarkan pertanyaan secara seragam.
- Pilihan enjin (SaaS, sumber terbuka atau pangkalan data) hendaklah berdasarkan jumlah data, kerumitan carian dan prestasi dan keperluan penyelenggaraan projek.
Apabila anda mula bekerja dengan Laravel dan memerlukan enjin carian masa nyata yang bertindak balas serta-merta , anda mudah tersesat di antara seribu pendekatan yang mungkin: AJAX dengan fetch, jQuery, Alpine.js, Scout dengan Algolia atau Meilisearch, penapisan bahagian hadapan, dan sebagainya. Berita baiknya ialah ekosistem Laravel sudah menyediakan hampir semua yang anda perlukan untuk membina enjin carian yang lancar dan pantas tanpa perlu dibebani.
Dalam artikel ini, anda akan mempelajari cara melaksanakan pelbagai jenis carian masa nyata dalam Laravel , daripada pelengkap automatik AJAX klasik hingga carian teks penuh menggunakan Laravel Scout dan enjin carian seperti Algolia, Meilisearch, pangkalan data itu sendiri atau Elasticsearch. Anda juga akan meneroka alternatif ringan dengan Alpine.js untuk menapis data secara langsung dalam pelayar apabila berurusan dengan set data kecil.
Apakah carian masa nyata dalam Laravel dan bagaimana asasnya berfungsi?
Idea di sebalik carian masa nyata ialah, apabila pengguna menaip dalam medan teks , pertanyaan akan dicetuskan dan hasilnya dikemas kini tanpa memuatkan semula halaman. Secara teknikalnya, ini melibatkan tiga komponen utama: bahagian belakang Laravel, JavaScript pelayar dan pertukaran data dalam format JSON.
Di satu pihak, Laravel bertindak sebagai lapisan pelayan yang bertanggungjawab untuk menerima permintaan, mentafsir parameter carian (teks yang dimasukkan), membuat pertanyaan pada pangkalan data dan mengembalikan respons berstruktur, biasanya dalam format JSON. Respons ini boleh menunjukkan kejayaan, ralat atau tiada hasil ditemui.
Di hujung yang satu lagi, JavaScript mengendalikan pendengaran peristiwa pengguna pada input carian, menghantar permintaan tak segerak (AJAX) ke bahagian belakang dan memaparkan data yang dikembalikan pada halaman tanpa memerlukan penyegaran penuh pelayar. Ini boleh dilakukan dengan pengambilan asli, jQuery AJAX atau pustaka reaktif kecil seperti Alpine.js.
Dengan mekanisme asas ini, anda boleh membina apa sahaja daripada pelengkap automatik mudah dengan beberapa rekod , kepada enjin carian teks penuh lanjutan dengan kerelevanan, penomboran halaman dan penapis, bergantung pada pustaka seperti Laravel Scout dan enjin carian luaran yang dioptimumkan untuk carian.
Model, laluan dan pengawal untuk enjin carian masa nyata asas
Sebelum anda mendalami JavaScript, anda memerlukan bahagian Laravel yang teratur: model Eloquent untuk mencari, laluan yang jelas dan pengawal yang dikhaskan untuk mengendalikan logik carian dalam masa nyata.
Langkah pertama ialah mempunyai model Eloquent yang mewakili jadual tempat anda akan mencari. Bayangkan jadual negara dan model yang sangat mudah dipanggil Country , tanpa cap waktu dan dengan tugasan pukal dibenarkan:
Contoh model Eloquent minimum untuk carian :
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;
}
Ini menunjukkan bahawa model Pais terletak dalam ruang nama Laravel standard , mewarisi daripada Model, dan membenarkan penugasan mana-mana medan dengan create() dengan membiarkan tatasusunan yang dijaga kosong. Dengan melumpuhkan cap waktu dengan public $timestamps = false, anda mengelakkan masalah jika jadual tidak mempunyai lajur created_at dan updated_at.
Langkah seterusnya adalah untuk menentukan laluan yang akan mengendalikan paparan enjin carian dan permintaan AJAX . Satu skema yang sangat biasa menggabungkan laluan GET untuk memaparkan paparan dan laluan POST yang direka untuk menerima pertanyaan dalam masa nyata:
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']);
Laluan akar mengembalikan paparan alu-aluan, manakala URL /search dikhaskan untuk fungsi carian . Kaedah index() pengawal memaparkan borang dan input carian, manakala kaedah search() memproses permintaan tak segerak yang dihantar daripada pelayar.
Dalam pengawal, anda boleh melaksanakan corak yang sangat praktikal: sediakan tatasusunan tindak balas lalai sekiranya berlaku ralat dan hanya tulis ganti apabila ia sebenarnya merupakan permintaan AJAX yang sah dan pertanyaan dilaksanakan tanpa masalah.
Pengawal boleh mempunyai struktur yang serupa dengan ini:
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);
}
}
Pada ketika ini, anda mempunyai kitaran backend yang lengkap: permintaan AJAX masuk, pengesahan bahawa ia sememangnya AJAX, pertanyaan menggunakan `where like`, dan mengehadkan bilangan hasil kepada jumlah yang munasabah dengan `take(10)` untuk mengelakkan beban pangkalan data yang berlebihan. Respons sentiasa dihantar dalam JSON, yang sangat memudahkan kerja frontend.
Paparan bilah dan pengambilan JavaScript untuk carian reaktif
Dengan model, laluan dan pengawal sedia, tiba masanya untuk membina bahagian yang boleh dilihat: borang dengan medan carian dan blok untuk memaparkan hasil , serta JavaScript yang bertanggungjawab untuk membuat permintaan di latar belakang.
Paparan Blade boleh menjadi sangat mudah, bergantung pada token CSRF yang disuntik oleh Laravel untuk mengesahkan permintaan POST dan pada input carian yang mudah digunakan:
<!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>
Dalam contoh ini, skrip mendengar peristiwa keyup pada input carian , jadi setiap ketukan kekunci mencetuskan permintaan ambil ke laluan /search. Teks semasa medan dihantar dalam format JSON dan pengepala kunci seperti X-Requested-With disertakan untuk menunjukkan bahawa ia adalah AJAX, bersama-sama dengan token CSRF untuk memintas perlindungan natif Laravel.
Apabila respons tiba, ia akan diubah menjadi JSON dan senarai HTML kecil dengan hasilnya dijana secara dinamik , atau mesej seperti "Tiada hasil ditemui" dipaparkan jika pertanyaan tidak mengembalikan data. Semua ini berlaku tanpa memuatkan semula halaman, secara semula jadi untuk pengguna.
Corak ini boleh diperhalusi lagi dengan butiran UX yang kecil, seperti menambah debounce antara ketukan kekunci, memaparkan loader atau mengendalikan ralat rangkaian untuk mengelakkan antara muka daripada kelihatan beku apabila sesuatu gagal.
Carian langsung dengan Laravel dan AJAX menggunakan jQuery
Walaupun pengambilan telah mendapat sambutan yang ketara, jQuery AJAX kekal sangat popular dalam projek legasi atau pasukan yang telah menyepadukannya. Ideanya adalah sama: menangkap apa yang ditaip pengguna, membuat permintaan tak segerak dan menyegarkan semula DOM.
Aliran kerja biasa dengan jQuery dalam Laravel untuk carian langsung biasanya merangkumi langkah-langkah asas ini: tentukan laluan tertentu, cipta pengawal khusus, bina paparan Blade dengan input carian dan akhirnya tambahkan kod jQuery yang mencetuskan AJAX semasa ia ditaip.
Prosesnya berfungsi seperti ini: apabila pengguna mula menaip, jQuery menghantar pertanyaan ke pelayan dengan rentetan carian. Laravel menapis maklumat dalam pangkalan data, mengembalikan objek JSON dengan hasil yang sepadan, dan jQuery mengemas kini bekas HTML pada halaman untuk mencerminkan padanan, semuanya dalam masa beberapa milisaat.
Kelebihan menggunakan jQuery ialah ia memudahkan sintaks AJAX dan sangat mudah dibaca jika anda sudah mempunyai pustaka dalam projek anda. Walau bagaimanapun, ia memperkenalkan kebergantungan tambahan yang mungkin tidak diperlukan jika anda boleh menggunakan JavaScript moden dan fungsi pengambilan asli.
Penapisan masa nyata dan carian pada bahagian hadapan dengan Alpine.js
Apabila data yang hendak dipaparkan agak kecil (contohnya, kurang daripada 50 item ), tidak selalunya berbaloi untuk menyediakan backend dengan carian yang kompleks. Dalam kes ini, pilihan yang sangat mudah adalah menapis terus dalam pelayar menggunakan Alpine.js , tanpa membuat permintaan kepada pelayan semasa pengguna menaip.
Ideanya adalah untuk mengira rentetan carian terlebih dahulu untuk setiap item (cth., nama, perihalan dan kategori dalam huruf kecil), menyimpannya dalam atribut data-search-text dan membiarkan Alpine.js mengendalikan paparan atau penyembunyian item berdasarkan teks yang dimasukkan dalam medan carian.
Komponen Alpine.js boleh mempunyai struktur yang serupa dengan ini: 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;
},
}
Dalam paparan, setiap kad atau baris data akan mempunyai atribut data-search-text dengan teks yang telah disediakan dalam huruf kecil , jadi penapis dikurangkan kepada includes() dalam JavaScript, sangat pantas untuk senarai pendek:
<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>
Selain itu, anda boleh memaparkan blok status kosong hanya apabila tiada hasil untuk istilah carian semasa , menjemput pengguna untuk mengubah suai teks atau mengosongkan medan dengan butang yang hanya menetapkan semula carian kepada rentetan kosong.
Pendekatan ini mempunyai kelebihan yang jelas: tiada panggilan pelayan semasa carian , interaksi berlaku secara serta-merta, dan logiknya kekal sangat setempat dan mudah untuk dinyahpepijat. Ia sesuai untuk pemilih pantas, modal pemilihan item atau katalog kecil yang terbenam dalam halaman Laravel.
Laravel Scout: Carian teks penuh dengan enjin khusus
Apabila keadaan menjadi serius dan anda memerlukan carian teks penuh yang pantas, relevan dan boleh diskala , laluan semula jadi dalam Laravel ialah Laravel Scout. Scout ialah lapisan integrasi yang membolehkan anda menghubungkan model Eloquent anda dengan enjin carian seperti Algolia, Meilisearch, pangkalan data anda sendiri, koleksi dalam memori atau Elasticsearch melalui pengawal luaran.
Untuk bermula dengan Scout, pendekatan biasa adalah dengan mencipta projek Laravel baharu atau menggunakan semula projek sedia ada , melancarkannya dengan Docker (contohnya, menggunakan Laravel Sail), dan kemudian memasang pustaka dengan Composer. Setelah selesai, anda menerbitkan fail konfigurasi scout.php dan melaraskan pembolehubah persekitaran mengikut pemacu yang anda ingin gunakan.
Aliran kerja yang biasa adalah memasang Scout dengan Composer, menerbitkan konfigurasinya dan mendayakan baris gilir pengindeksan dengan `SCOUT_QUEUE=true` dalam fail `.env` supaya operasi intensif sumber diproses di latar belakang, sekali gus meningkatkan masa tindak balas aplikasi. Di samping itu, anda harus memastikan bahawa `DB_HOST` menghala ke pangkalan data yang anda gunakan, yang amat penting jika anda menggunakan kontena Docker.
Agar model dapat menyertai carian Scout, ia mesti ditandakan secara eksplisit sebagai boleh dicari dengan menambah ciri `Boleh Dicari` . Contohnya, jika anda mempunyai model `Kereta Api` yang mewakili jadual kereta api dengan medan `tajuk`, anda boleh mentakrifkannya seperti ini:
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';
}
}
Kaedah `searchableAs` membolehkan anda menyesuaikan nama indeks dalam enjin carian , dan bukannya menggunakan nama lalai yang diperoleh daripada model. Dari situ, Scout mengendalikan penyegerakan operasi penciptaan, kemas kini dan pemadaman dengan indeks jauh atau setempat, bergantung pada pemacu yang dipilih.
Pengakap Laravel dengan Algolia: Carian SaaS sepantas kilat
Algolia ialah perkhidmatan SaaS yang memberi tumpuan kepada penyediaan carian yang sangat pantas dan relevan merentasi jumlah data yang besar . Ia menampilkan panel web untuk mengurus indeks, peraturan kerelevanan, sinonim dan banyak lagi, serta berintegrasi dengan lancar dengan Laravel melalui Scout dan klien PHP rasmi.
Untuk menggunakan Algolia dengan Scout, anda perlu memasang klien PHPnya menggunakan Composer, mendaftarkan kelayakan anda dalam fail .env (ID Aplikasi dan Kunci API Pentadbir), dan mengkonfigurasi SCOUT_DRIVER=algolia untuk memberitahu Scout menggunakan enjin ini. Anda boleh mendapatkan kedua-dua ID aplikasi dan kunci pentadbir daripada papan pemuka Algolia.
Sebaik sahaja persekitaran disediakan, anda boleh menggunakan kaedah seperti Train::search('text')->paginate(6) secara langsung dalam pengawal anda untuk melakukan carian pada medan yang diindeks, menerima hasil dalam format Eloquent yang dihalaman yang sedia untuk dihantar ke paparan Blade.
Contohnya , anda boleh mempunyai pengawal indeks yang menyenaraikan semua tren atau melakukan carian jika parameter titlesearch diluluskan, dan kaedah create untuk memasukkan tren baharu ke dalam indeks:
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();
}
Dalam paparan yang sepadan, anda boleh menggabungkan borang untuk menambah tren baharu dan borang GET yang lain dengan medan carian tajuk yang mencetuskan carian semasa penyerahan. Kemudian anda hanya perlu mengulang koleksi tren dan memaparkan medannya dalam jadual, memanfaatkan pautan penomboran yang dijana oleh Laravel.
Pengakap dengan Meilisearch, pangkalan data dan koleksi
Jika anda lebih suka mengelakkan perkhidmatan luaran, Meilisearch ialah enjin carian sumber terbuka yang boleh anda gunakan secara setempat atau pada infrastruktur anda. Scout berintegrasi dengan Meilisearch dengan cara yang hampir sama dengan Algolia, hanya dengan menukar pemacu dan menambah pembolehubah MEILISEARCH_HOST dan MEILISEARCH_KEY pada fail .env.
Untuk menggunakannya, pasang klien PHP Meilisearch, tetapkan SCOUT_DRIVER=meilisearch , dan halakan MEILISEARCH_HOST ke URL tika (contohnya, http://127.0.0.1:7700). Jika anda sudah mempunyai rekod, anda boleh mengindeksnya dengan arahan php artisan scout:import "App\Models\Train" supaya enjin menyediakannya.
Untuk aplikasi yang lebih kecil atau bersaiz sederhana, anda juga boleh memilih pemacu pangkalan data Scout , yang memanfaatkan indeks teks penuh dan pernyataan LIKE pada pangkalan data MySQL atau PostgreSQL anda. Dalam kes ini, anda tidak memerlukan perkhidmatan luaran; cuma tetapkan SCOUT_DRIVER=database untuk Scout menggunakan pangkalan data itu sendiri sebagai enjin cariannya.
Satu lagi pilihan menarik ialah pemacu koleksi, yang berfungsi dengan koleksi Eloquent dalam memori . Enjin ini menapis hasil menggunakan kaedah `where` dan penapisan koleksi, dan ia serasi dengan mana-mana pangkalan data yang disokong oleh Laravel. Anda boleh mengaktifkannya dengan `SCOUT_DRIVER=collection` atau dengan melaraskan fail konfigurasi Scout jika anda mahukan sesuatu yang lebih spesifik.
Integrasi dengan Elasticsearch menggunakan Explorer
Jika keperluan carian anda melibatkan penggunaan data dalam jumlah yang besar dan analitik masa nyata , Elasticsearch adalah yang klasik. Dalam ekosistem Laravel, cara moden untuk mengintegrasikannya dengan Scout adalah dengan menggunakan pengawal Explorer, yang bertindak sebagai jambatan antara model anda dan kluster Elasticsearch.
Ini biasanya melibatkan penggunaan Docker dan fail docker-compose kaya yang dilancarkan, selain daripada perkhidmatan biasa (Laravel, MySQL, Redis, Meilisearch, dll.), bekas Elasticsearch dan Kibana . Kemudian anda memasang pakej jeroen-g/explorer melalui Composer dan menerbitkan fail konfigurasinya untuk menentukan model mana yang harus diindeks.
Dalam fail config/explorer.php, anda boleh mendaftarkan model anda di bawah kekunci indexes, contohnya dengan menambah App\Models\Train::class . Selain itu, anda menukar pemacu daripada Scout kepada Elasticsearch dalam fail .env dengan SCOUT_DRIVER=elastic supaya semuanya menghala ke Elasticsearch.
Dalam model Train, anda perlu melaksanakan antara muka Explored dan menggantikan kaedah mappableAs , yang mentakrifkan peta medan yang akan dihantar ke indeks. Contoh minimum ialah:
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,
];
}
}
Dari sini, anda boleh melancarkan carian pada Elasticsearch menggunakan antara muka Scout yang sama , mendapat manfaat daripada masa tindak balas yang sangat rendah dan kuasa pertanyaan penuh enjin ini, tetapi tanpa meninggalkan ekosistem Laravel.
Dengan semua pendekatan ini—daripada pelengkap automatik asas dengan pengambilan atau jQuery, kepada penapisan bahagian hadapan dengan Alpine.js, kepada carian teks penuh dengan Laravel Scout dan pelbagai pemacu— Laravel memberi anda pelbagai pilihan untuk melaksanakan carian masa nyata yang disesuaikan dengan saiz projek anda, prestasi yang anda perlukan dan infrastruktur yang anda sanggup kekalkan.