- Ларавел вам омогућава да имплементирате све, од једноставних претраживача са AJAX-ом до напредних претрага целог текста користећи Laravel Scout и екстерне претраживаче попут Algolia, Meilisearch или Elasticsearch.
- За једноставне претраге, филтрирање на фронтенду помоћу Alpine.js-а или помоћу изворних захтева за преузимање избегава преоптерећење сервера и побољшава корисничко искуство у малим листама.
- Laravel Scout централизује интеграцију са различитим претраживачима и олакшава обележавање модела као претраживих, управљање индексима и једнообразно покретање упита.
- Избор система (SaaS, отвореног кода или база података) треба да се заснива на количини података, сложености претрага и захтевима пројекта у погледу перформанси и одржавања.
Када почнете да радите са Laravel-ом и потребан вам је претраживач у реалном времену који тренутно реагује , лако се изгубите међу хиљаду могућих приступа: AJAX са fetch-ом, jQuery, Alpine.js, Scout са Algolia-ом или Meilisearch-ом, филтрирање на фронтенду итд. Добра вест је да Laravel екосистем већ пружа практично све што вам је потребно за изградњу глатког и брзог претраживача без преоптерећења.
У овом чланку ћете научити како да имплементирате различите врсте претраживања у реалном времену у Laravel-у , од класичног AJAX аутоматског допуњавања до претраживања целог текста користећи Laravel Scout и претраживаче попут Algolia, Meilisearch, саме базе података или чак Elasticsearch-а. Такође ћете истражити једноставне алтернативе са Alpine.js-ом за филтрирање података директно у прегледачу када се ради са малим скуповима података.
Шта је претрага у реалном времену у Ларавелу и како основе функционишу?
Идеја која стоји иза претраге у реалном времену је да се, док корисник куца у текстуално поље , покреће упит и резултати се ажурирају без поновног учитавања странице. Технички, ово укључује три кључне компоненте: Laravel бекенд, JavaScript прегледача и размену података у JSON формату.
С једне стране, Laravel делује као серверски слој одговоран за пријем захтева, тумачење параметара претраге (унетог текста), упите бази података и враћање структурираног одговора, обично у JSON формату. Овај одговор може указивати на успех, грешку или да нису пронађени резултати.
На другом крају, Јаваскрипт обрађује слушање корисничких догађаја на уносу за претрагу, слање асинхроних захтева (AJAX) бекенду и приказивање враћених података на страници без потребе за потпуним освежавањем прегледача. То се може урадити помоћу нативног fetch-а, jQuery AJAX-а или малих реактивних библиотека попут Alpine.js.
Овим основним механизмом можете направити било шта, од једноставног аутоматског допуњавања са неколико записа , до напредне претраживачке машине за цео текст са релевантношћу, пагинацијом и филтерима, ослањајући се на библиотеке попут Laravel Scout-а и екстерне претраживаче оптимизоване за претраге.
Модел, руте и контролер за основни претраживач у реалном времену
Пре него што се упустите у ЈаваСкрипт, потребно је да Ларавел страна буде добро организована: Елоквент модел за претрагу, јасне руте и контролер посвећен руковању логиком претраге у реалном времену.
Први корак је да имате 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;
}
Ово указује да се Pais модел налази у стандардном 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']);
Коренска рута враћа приказ добродошлице, док је URL адреса /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);
}
}
У овом тренутку, имате комплетан бекенд циклус: долазни AJAX захтев, верификација да је заиста AJAX, упит користећи `where like` и ограничавање броја резултата на разумну количину помоћу `take(10)` како би се избегло преоптерећење базе података. Одговор се увек шаље у JSON формату, што знатно поједностављује рад фронтенда.
Приказ бленде и JavaScript дохват за реактивну претрагу
Када су модел, руте и контролер спремни, време је да се направи видљиви део: образац са пољем за претрагу и блоком за приказивање резултата , плус Јаваскрипт одговоран за слање захтева у позадини.
Blade приказ може бити веома једноставан, ослањајући се на 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>
У овом примеру, скрипта ослушкује догађај притиска тастера на уносу за претрагу , тако да сваки притисак тастера покреће захтев за преузимање ка путањи /search. Тренутни текст поља се шаље у JSON формату, а кључни заглавља као што је X-Requested-With су укључена да би се назначило да је у питању AJAX, заједно са CSRF токеном да би се заобишла Laravel-ова изворна заштита.
Када стигне одговор, он се трансформише у JSON и динамички се генерише мала HTML листа са резултатима или се приказује порука као што је „Није пронађен ниједан резултат“ ако упит не врати никакве податке. Све се ово дешава без поновног учитавања странице, на природан начин за корисника.
Овај образац се може додатно усавршити малим UX детаљима, као што је додавање одскока између притисака тастера, приказивање програма за учитавање или руковање мрежним грешкама како би се спречило да интерфејс изгледа замрзнуто када нешто крене неуспешно.
Претрага уживо са Laravel-ом и AJAX-ом користећи jQuery
Иако је fetch добио значајан утицај, jQuery AJAX остаје веома популаран у старијим пројектима или тимовима који га већ имају интегрисаног. Идеја је потпуно иста: снимити шта корисник куца, направити асинхрони захтев и освежити DOM.
Типичан ток рада са jQuery-јем у Laravel-у за претрагу уживо обично укључује ове основне кораке: дефинисање одређене руте, креирање наменског контролера, изградња Blade приказа са уносом за претрагу и коначно додавање jQuery кода који покреће AJAX док се куца.
Процес функционише овако: када корисник почне да куца, jQuery шаље упит серверу са низом за претрагу. Laravel филтрира информације у бази података, враћа JSON објекат са подударајућим резултатима, а jQuery ажурира HTML контејнер на страници како би одражавао подударања, све у року од неколико милисекунди.
Предност коришћења jQuery-ја је у томе што значајно поједностављује AJAX синтаксу и веома је једноставан за читање ако већ имате библиотеку у свом пројекту. Међутим, уводи додатну зависност која можда није неопходна ако можете да радите са модерним JavaScript-ом и нативном функционалношћу преузимања.
Филтрирање и претрага у реалном времену на фронтенду помоћу Alpine.js-а
Када су подаци који треба да се прикажу релативно мали (на пример, мање од 50 ставки ), није увек исплативо подешавати бекенд са сложеним претрагама. У тим случајевима, веома погодна опција је директно филтрирање у прегледачу помоћу Alpine.js-а , без слања захтева серверу док корисник куца.
Идеја је да се унапред израчуна стринг за претрагу за сваку ставку (нпр. име, опис и категорија малим словима), сачува га у атрибуту data-search-text и дозволи Alpine.js-у да обрађује приказивање или скривање ставки на основу текста унетог у поље за претрагу.
Компонента Alpine.js може имати структуру сличну овој: 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;
},
}
У приказу, свака картица или ред података би имао атрибут data-search-text са текстом који је већ припремљен малим словима , тако да се филтер своди на 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 Scout. Scout је интеграциони слој који вам омогућава да лако повежете своје Eloquent моделе са претраживачима као што су Algolia, Meilisearch, вашом базом података, колекцијама у меморији или чак Elasticsearch-ом путем екстерних контролера.
Да бисте започели са Scout-ом, уобичајени приступ је да креирате нови Laravel пројекат или поново користите постојећи , покренете га помоћу Docker-а (на пример, користећи Laravel Sail), а затим инсталирате библиотеку помоћу Composer-а. Када то урадите, објавите конфигурациону датотеку scout.php и подесите променљиве окружења према драјверу који желите да користите.
Типичан ток рада би био да се инсталира Scout са Composer-ом, објави његова конфигурација и омогући ред за индексирање са `SCOUT_QUEUE=true` у `.env` датотеци тако да се операције које захтевају много ресурса обрађују у позадини, побољшавајући време одзива апликације. Поред тога, требало би да се уверите да `DB_HOST` указује на базу података коју користите, што је посебно важно ако користите Docker контејнере.
Да би модел учествовао у претрагама Scout-а, мора бити експлицитно означен као претражив додавањем особине `Searchable` . На пример, ако имате модел `Train` који представља табелу возова са пољем `title`, можете га дефинисати овако:
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 обрађује синхронизацију операција креирања, ажурирања и брисања са удаљеним или локалним индексом, у зависности од изабраног драјвера.
Laravel Scout са Algolia-ом: Муњевито брза SaaS претрага
Алголиа је SaaS услуга фокусирана на пружање веома брзих и релевантних претрага у великим количинама података . Садржи веб панел за управљање индексима, правилима релевантности, синонимима и још много тога, и беспрекорно се интегрише са Ларавелом преко Скаута и званичног ПХП клијента.
Да бисте користили Алголију са Скаутом, потребно је да инсталирате њен ПХП клијент помоћу Композитора, региструјете своје акредитиве у .env датотеци (ИД апликације и администраторски АПИ кључ) и конфигуришете SCOUT_DRIVER=algolia да бисте рекли Скауту да користи овај механизам. Можете добити и ИД апликације и администраторски кључ са Алголијине контролне табле.
Када је окружење подешено, можете користити методе попут Train::search('text')->paginate(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 образац са пољем за претрагу наслова које покреће претрагу након слања. Затим једноставно итерирате кроз колекцију возова и приказујете њихова поља у табели, користећи предности пагинационих линкова које генерише Laravel.
Извиђач са Meilisearch-ом, базом података и колекцијама
Ако више волите да избегавате екстерне сервисе, Meilisearch је претраживач отвореног кода који можете да примените локално или на својој инфраструктури. Scout се интегрише са Meilisearch-ом на веома сличан начин као Algolia, једноставном променом драјвера и додавањем променљивих MEILISEARCH_HOST и MEILISEARCH_KEY у .env датотеку.
Да бисте га користили, инсталирајте Meilisearch PHP клијент, подесите 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-compose датотеком која покреће, поред уобичајених сервиса (Laravel, MySQL, Redis, Meilisearch, итд.), Elasticsearch и Kibana контејнере . Затим инсталирате пакет jeroen-g/explorer путем Composer-а и објављујете његову конфигурациону датотеку да бисте одредили који модели треба да буду индексирани.
У датотеци config/explorer.php можете регистровати своје моделе под кључем indexes, на пример додавањем App\Models\Train::class . Поред тога, мењате драјвер из Scout у Elasticsearch у .env датотеци са SCOUT_DRIVER=elastic тако да све указује на Elasticsearch.
Унутар Train модела, потребно је да имплементирате Explored интерфејс и да надјачате метод mappableAs , који дефинише мапу поља која ће се послати индексу. Минималан пример би био:
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 вам пружа огроман распон опција за имплементацију претрага у реалном времену прилагођених величини вашег пројекта, перформансама које су вам потребне и инфраструктури коју сте спремни да одржавате.