מדריך מלא לחיפוש בזמן אמת ב-Laravel

העדכון אחרון: 5 דצמבר 2025
מחבר: TecnoDigital
  • Laravel מאפשרת לך ליישם כל דבר, החל ממנועי חיפוש פשוטים עם AJAX ועד חיפושים מתקדמים בטקסט מלא באמצעות Laravel Scout ומנועי חיפוש חיצוניים כמו Algolia, Meilisearch או Elasticsearch.
  • עבור חיפושים קלים, סינון בקצה הקדמי באמצעות Alpine.js או באמצעות בקשות אחזור מקוריות מונע עומס יתר על השרת ומשפר את חוויית המשתמש ברשימות קטנות.
  • Laravel Scout מרכזת את האינטגרציה עם מנועי חיפוש שונים ומקלה על סימון מודלים כניתנים לחיפוש, ניהול אינדקסים והפעלת שאילתות באופן אחיד.
  • בחירת מנוע החיפוש (SaaS, קוד פתוח או מסד נתונים) צריכה להתבסס על נפח הנתונים, מורכבות החיפושים ודרישות הביצועים והתחזוקה של הפרויקט.

חיפוש בזמן אמת ב-Laravel

כשאתה מתחיל לעבוד עם Laravel וצריך מנוע חיפוש בזמן אמת שמגיב באופן מיידיקל ללכת לאיבוד בין אלף גישות אפשריות: AJAX עם fetch, jQuery, Alpine.js, Scout עם Algolia או Meilisearch, סינון חזיתי וכו'. החדשות הטובות הן שהמערכת האקולוגית של Laravel כבר מספקת כמעט כל מה שצריך כדי להגדיר חיפוש חלק ומהיר מבלי למות בניסיון.

במאמר זה תראו כיצד להרכיב סוגים שונים של חיפוש בזמן אמת ב-Laravelמהשלמה אוטומטית קלאסית של AJAX ועד חיפושי טקסט מלא עם Laravel Scout ומנועי חיפוש כמו Algolia, Meilisearch, מסד הנתונים עצמו, או אפילו Elasticsearch. תראו גם חלופות קלות משקל עם Alpine.js לסינון נתונים ישירות בדפדפן כאשר נפח הנתונים קטן.

מהו חיפוש בזמן אמת ב-Laravel וכיצד הבסיס עובד?

הרעיון מאחורי חיפוש בזמן אמת הוא ש... כאשר המשתמש מקליד בשדה טקסטשאילתה מופעלת והתוצאות מתעדכנות מבלי לטעון מחדש את הדף. מבחינה טכנית, זה כרוך בשלושה רכיבים מרכזיים: קצה השרת של Laravel, ה-JavaScript של הדפדפן וחילופי נתונים בפורמט JSON.

מצד אחד, Laravel משמשת כשכבת השרת הוא אחראי על קבלת בקשות, פירוש פרמטרי חיפוש (הטקסט שהוזן), ביצוע שאילתות למסד הנתונים והחזרת תגובה מובנית, בדרך כלל בפורמט JSON. תגובה זו יכולה להצביע על הצלחה, שגיאה או שלא נמצאו תוצאות.

בקצה השני, ג'אווהסקריפט אחראי על האזנה לאירועי משתמש. בקלט החיפוש, שלח בקשות אסינכרוניות (AJAX) לשרת האחורי והצג את הנתונים המוחזרים בדף מבלי שהדפדפן יבצע רענון מלא. ניתן לעשות זאת באמצעות fetch native, jQuery AJAX, או ספריות ריאקטיביות קטנות כמו Alpine.js.

בעזרת מנגנון בסיסי זה ניתן לבנות מ- השלמה אוטומטית פשוטה עם מספר מצומצם של רשומות, עד למנוע חיפוש טקסט מלא מתקדם עם רלוונטיות, עימוד ומסננים, הנתמך על ידי ספריות כמו Laravel Scout ומנועי חיפוש חיצוניים המותאמים לחיפוש.

מודל, נתיבים ובקר עבור מנוע חיפוש בסיסי בזמן אמת

לפני שאתם מתעמקים ב-JavaScript, עליכם לוודא שצד Laravel מאורגן היטב: מודל רהוט לחיפוש, נתיבים ברורים ובקר ייעודי לנהל את לוגיקת החיפוש בזמן אמת.

הצעד הראשון הוא ליצור מודל Eloquent המייצג את הטבלה שבה אתם הולכים לחפש. דמיינו טבלת מדינות ומודל שנקרא מדינה פשוט מאוד, ללא חותמות זמן ועם אפשרות להקצאה בכמות גדולה:

דוגמה למודל מינימלי של Eloquent לחיפושים:

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

מצוין כאן כי המודל פאיס ממוקם במרחב השמות הסטנדרטי של Laravel.הוא יורש מ-Model ומאפשר לך להקצות כל שדה עם create() על ידי השארת המערך המוגן ריק. על ידי השבתת חותמות זמן עם public $timestamps = false, אתה נמנע מבעיות אם הטבלה אינה מכילה את העמודות created_at ו-updated_at.

השלב הבא הוא להגדיר הנתיבים שיטפלו הן בתצוגת מנוע החיפוש והן בבקשות AJAXסכמה נפוצה מאוד משלבת נתיב GET להצגת התצוגה ונתיב POST שנועד לקבל שאילתות בזמן אמת:

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

נתיב הבסיס מחזיר תצוגת ברוכים הבאים, בעוד שכתובת האתר /search שמור לפונקציונליות חיפושהמתודה index() של הבקר מציגה את הטופס ואת קלט החיפוש, בעוד ששיטת search() מעבדת בקשות אסינכרוניות הנשלחות מהדפדפן.

בבקר ניתן ליישם תבנית מעשית מאוד: הכן מערך תגובות ברירת מחדל למקרה של שגיאה ולהחליף אותו רק כאשר אכן מדובר בבקשת AJAX תקפה והשאילתה מבוצעת ללא בעיות.

ייתכן שלבקר יש מבנה דומה זֶה:

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

בשלב הזה כבר יש לך מחזור ה-backend המלא: בקשת AJAX נכנסת, בדיקה שמדובר ב-AJAX, שאילתה עם where like והגבלת התוצאות למספר סביר באמצעות take(10) כדי למנוע עומס יתר על מסד הנתונים. התגובה נשלחת תמיד ב-JSON, מה שמפשט מאוד את עבודת הקצה הקדמי.

תצוגת להב ואחזור JavaScript עבור חיפוש ריאקטיבי

לאחר שהמודל, הנתיבים והבקר מוכנים, הגיע הזמן לבנות את החלק הנראה לעין: טופס עם שדה חיפוש ובלוק להצגת התוצאות, בנוסף ל-JavaScript שאחראי על ביצוע בקשות ברקע.

תצוגת הלהב יכולה להיות פשוטה מאוד, בהסתמך על אסימון CSRF אשר Laravel מזריק כדי לאמת בקשות POST ובקלט חיפוש שנוח לשימוש:

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

בדוגמה זו הסקריפט האזינו לאירוע keyup בקלט החיפושכל לחיצה מפעילה בקשת אחזור (fetch request) לנתיב /search. הטקסט הנוכחי של השדה נשלח בפורמט JSON, וכותרות מפתח כגון X-Requested-With כלולות כדי לציין שמדובר ב-AJAX, יחד עם אסימון CSRF כדי לעקוף את ההגנה המקורית של Laravel.

כאשר התגובה מגיעה, היא הופכת ל-JSON ונוצרת באופן דינמי. רשימת HTML קטנה עם התוצאותאו הודעה כמו "לא נמצאו תוצאות" כאשר השאילתה לא מחזירה נתונים. כל זאת מבלי לטעון מחדש את הדף, בצורה טבעית עבור המשתמש.

ניתן לעדן עוד יותר את התבנית הזו באמצעות פרטי חוויית משתמש קטנים, כגון הוספת עיכוב (debounce) בין הקשות מקלדת, להציג טוען או לטפל בשגיאות רשת כדי למנוע מהממשק להיראות קפוא כאשר משהו נכשל.

חיפוש חי עם Laravel ו-AJAX באמצעות jQuery

למרות ש-fetch צבר תאוצה רבה בימינו, jQuery AJAX נשאר פופולרי מאוד בפרויקטים מדור קודם או בצוותים שכבר מיושם בהם. הרעיון זהה לחלוטין: ללכוד את מה שהמשתמש מקליד, לבצע בקשה אסינכרונית ולרענן את ה-DOM.

תהליך עבודה טיפוסי עם jQuery ב-Laravel לחיפוש חי כולל בדרך כלל את השלבים הבסיסיים הבאים: להגדיר מסלול ספציפי, ליצור בקר ייעודי, לבנות את תצוגת ה-Blade עם קלט החיפוש ולבסוף, הוסיפו את קוד jQuery שמפעיל את AJAX בזמן שהוא מוקלד.

התהליך עובד כך: כאשר המשתמש מתחיל להקליד, jQuery שולח שאילתה לשרת עם מחרוזת החיפוש. Laravel מסנן את המידע במסד הנתונים, מחזיר JSON עם התוצאות התואמות, ו-jQuery מעדכן קונטיינר HTML בדף כדי לשקף את ההתאמות, והכל תוך אלפיות השנייה.

היתרון של שימוש ב-jQuery הוא ש... זה פחות או יותר מסכם את התחביר של AJAX וזה מאוד פשוט לקריאה אם ​​כבר יש לך את הספרייה בפרויקט שלך. עם זאת, אתה מוסיף תלות נוספת שעשויה לא להיות הכרחית אם אתה יכול לעבוד עם JavaScript מודרני ו-native fetch.

סינון וחיפוש בזמן אמת בממשק המשתמש עם Alpine.js

כאשר הנתונים שיוצגו הם קטנים יחסית (לדוגמה, פחות מ-50 פריטים), לא תמיד כדאי להקים מערכת חיפושים מורכבת. במקרים כאלה, אפשרות נוחה מאוד היא סנן ישירות בדפדפן עם Alpine.js, מבלי לבצע בקשות לשרת בזמן שהמשתמש מקליד.

הרעיון הוא לחשב מראש מחרוזת חיפוש עבור כל אלמנט (לדוגמה, שם, תיאור וקטגוריה באותיות קטנות), לאחסן אותה בתכונה data-search-text ולתת ל-Alpine.js לטפל בשאר. הצג או הסתר אלמנטים בהתאם לטקסט הכתוב בשדה חיפוש.

לרכיב Alpine.js יכול להיות מבנה דומה לזה: סינון פריטים

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

בתצוגה, כל כרטיס או שורת נתונים יישאו תכונה טקסט חיפוש נתונים עם הטקסט שכבר מוכן באותיות קטנותלכן, המסנן מצטמצם לפונקציית includes() ב-JavaScript, שהיא מהירה מאוד עבור רשימות קצרות:

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

בנוסף, ניתן להציג בלוק מצב ריק רק כאשר אין תוצאות עבור מונח החיפוש הנוכחי.מזמין את המשתמש לשנות את הטקסט או לנקות את השדה באמצעות כפתור שפשוט מאפס את החיפוש למחרוזת ריקה.

לגישה זו יתרונות ברורים: אין קריאות לשרת במהלך החיפוש.האינטראקציה היא כמעט מיידית, והלוגיקה נשארת מקומית מאוד וקלה לניפוי באגים. זה מושלם עבור בוררים מהירים, מודלים לבחירת פריטים או קטלוגים קטנים המוטמעים בדף Laravel.

Laravel Scout: חיפוש טקסט מלא עם מנועי ייעוד

כשהדברים נהיים רציניים ואתה צריך חיפושי טקסט מלא מהירים, רלוונטיים וניתנים להרחבההנתיב הטבעי ב-Laravel הוא Laravel Scout. Scout היא שכבת אינטגרציה המאפשרת לך לחבר בקלות את מודלי Eloquent שלך למנועי חיפוש כמו Algolia, Meilisearch, מסד הנתונים שלך, אוספים בזיכרון, או אפילו Elasticsearch דרך בקרים חיצוניים.

כדי להתחיל עם סקאוט, הדבר הרגיל הוא צור פרויקט Laravel חדש או שימוש חוזר בפרויקט קייםכדי להפעיל אותו, השתמשו ב-Docker (לדוגמה, עם Laravel Sail) ולאחר מכן התקינו את הספרייה עם Composer. לאחר שתסיימו, פרסמו את קובץ התצורה scout.php והתאימו את משתני הסביבה בהתאם לדרייבר שברצונכם להשתמש בו.

תהליך עבודה טיפוסי יהיה להתקין את Scout עם Composer, לפרסם את התצורה שלו, ו הפעל את תור האינדוקס עם SCOUT_QUEUE=true בקובץ ה-.env, ודא שפעולות עתירות משאבים מעובדות ברקע, מה שמשפר את זמני התגובה של היישומים. בנוסף, עליך לוודא ש-DB_HOST מצביע למסד הנתונים בו אתה משתמש, דבר שחשוב במיוחד אם אתה משתמש במכולות Docker.

כדי שדוגמן יוכל להשתתף בחיפושי סיירים, יש צורך ב- כדי לסמן אותו במפורש כניתן לחיפוש על ידי הוספת המאפיין ניתן לחיפושלדוגמה, אם יש לכם מודל רכבת המייצג טבלת רכבות עם שדה כותרת, תוכלו להגדיר אותו כך:

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

שיטת searchableAs מאפשרת התאם אישית את שם האינדקס במנוע החיפושבמקום להשתמש בשם ברירת המחדל הנגזר מהמודל, Scout משתלט. מכאן, Scout מטפל בסנכרון פעולות היצירה, העדכון והמחיקה עם האינדקס המרוחק או המקומי, בהתאם למנהל ההתקן שנבחר.

Laravel Scout עם Algolia: חיפוש SaaS מהיר כברק

אלגוליה הוא שירות SaaS המתמקד ב להציע חיפושים מהירים ורלוונטיים מאוד על פני כמויות גדולות של נתוניםיש לו פאנל אינטרנט לניהול אינדקסים, כללי רלוונטיות, מילים נרדפות וכו', והוא משתלב היטב עם Laravel דרך Scout ולקוח ה-PHP הרשמי.

כדי להשתמש ב-Algolia עם Scout, תצטרכו להתקין את לקוח ה-PHP שלו עם Composer, לרשום את פרטי הגישה שלכם בקובץ .env (מזהה אפליקציה ומפתח API של מנהל מערכת), ו- הגדר SCOUT_DRIVER=algolia כדי להורות ל-Scout להשתמש במנוע זה. מלוח Algolia ניתן לקבל גם את מזהה האפליקציה וגם את מפתח הניהול.

לאחר הגדרת הסביבה, ניתן להשתמש בשיטות כגון Train::search('text')->pagente(6) ישירות לבקרים שלך כדי לבצע חיפושים בשדות המאוינדקסים, ולקבל תוצאות בפורמט Eloquent ממוספר עמודים מוכנות להעברה לתצוגת Blade.

למשליכול להיות לך בקר מדד שמפרט את כל הרכבות או מבצע חיפוש אם מתקבל פרמטר titlesearch, ושיטת create להוספת רכבות חדשות לאינדקס:

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

בתצוגה המתאימה, ניתן לשלב טופס לרישום רכבות חדשות וטופס GET נוסף עם שדה titlesearch שמפעיל את החיפוש עם ההגשה. לאחר מכן, כל שעליכם לעשות הוא לעבור על אוסף הרכבות ולהציג את השדות שלהן בטבלה, תוך ניצול קישורי העמוד שנוצרו על ידי Laravel.

סייר עם Meilisearch, מסד נתונים ואוספים

אם אתם מעדיפים להימנע משירותים חיצוניים, Meilisearch הוא מנוע חיפוש בקוד פתוח שניתן לפרוס באופן מקומי או בתשתית שלך. Scout משתלב עם Meilisearch בצורה דומה מאוד ל-Algolia, פשוט על ידי שינוי הדרייבר והוספת המשתנים MEILISEARCH_HOST ו-MEILISEARCH_KEY לקובץ .env.

כדי להשתמש בו, עליך להתקין את לקוח ה-PHP של Meilisearch, להתאים אותו SCOUT_DRIVER=meilisearch ולכוון את MEILISEARCH_HOST לכתובת ה-URL של המופע (לדוגמה, http://127.0.0.1:7700). אם כבר היו לך רשומות קודמות, תוכל לאנדקס אותן באמצעות הפקודה php artisan scout:import "App\Models\Train" כך שהן יהיו זמינות למנוע.

ביישומים קטנים או בינוניים, ניתן גם לבחור את מסד נתונים של נהגי Scoutזה ממנף אינדקסים של טקסט מלא ופקודות LIKE במסד הנתונים MySQL או PostgreSQL שלך. במקרה זה, אינך זקוק לשירות חיצוני; פשוט הגדר את SCOUT_DRIVER=database כדי ש-Scout ישתמש במסד הנתונים עצמו כמנוע החיפוש שלו.

אפשרות מעניינת נוספת היא אוסף מנהלי התקנים, שעובד על אוספי Eloquent בזיכרוןמנוע זה מסנן תוצאות באמצעות משפטי WHERE וסינון אוספים, והוא תואם לכל מסד נתונים הנתמך על ידי Laravel. ניתן להפעיל אותו באמצעות `SCOUT_DRIVER=collection` או על ידי התאמת קובץ התצורה של Scout להגדרות ספציפיות יותר.

אינטגרציה עם Elasticsearch באמצעות Explorer

אם צרכי החיפוש שלך כוללים עבודה עם כמויות עצומות של נתונים וניתוח בזמן אמתElasticsearch הוא קלאסיקה. במערכת האקולוגית של Laravel, דרך מודרנית לשלב אותו עם Scout היא להשתמש בבקר Explorer, הפועל כגשר בין המודלים שלך לבין אשכול Elasticsearch.

לשם כך, משתמשים בדרך כלל ב-Docker, יחד עם קובץ docker-compose עשיר אשר, בנוסף לשירותים הטיפוסיים (Laravel, MySQL, Redis, Meilisearch וכו'), מכולות Elasticsearch ו-Kibanaלאחר מכן אתה מתקין את חבילת jeroen-g/explorer דרך Composer ומפרסם את קובץ התצורה שלה כדי לציין אילו מודלים צריכים להיות לאנדקסים.

בקובץ config/explorer.php ניתן לרשום את המודלים שלכם תחת המפתח indexes, לדוגמה על ידי הוספת אפליקציה\מודלים\Train::classבנוסף, עליך לשנות את מנהל ההתקן של Scout ל-elastic בקובץ ה-.env עם SCOUT_DRIVER=elastic כך שהכל יצביע ל-Elasticsearch.

בתוך מודל ה-Train, יש ליישם את הממשק Explored ולעקוף את המתודה. ניתן למפות כ-אשר מגדיר את מפת השדות שיישלחו לאינדקס. דוגמה מינימלית תהיה:

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

מעכשיו, ניתן להפעיל חיפושים ב-Elasticsearch באמצעות אותו ממשק Scout., נהנים מזמני תגובה נמוכים מאוד ומכוח השאילתה המלא של מנוע זה, אך מבלי לעזוב את המערכת האקולוגית של Laravel.

עם כל הגישות הללו - החל מהשלמה אוטומטית בסיסית עם fetch או jQuery, דרך סינון ממשק משתמש עם Alpine.js, ועד חיפושי טקסט מלא עם Laravel Scout ודרייברים שונים - Laravel מעניקה לכם מגוון עצום של אפשרויות ליישום חיפושים בזמן אמת. מותאם לגודל הפרויקט שלך, לביצועים שאתה צריך ולתשתית שאתה מוכן לתחזק.

  הכל על מערכים בתכנות: סוגים, שימושים ודוגמאות