Введение
Laravel Scout предоставляет простое решение на основе драйверов для добавления полнотекстового поиска в ваши Eloquent-модели. С помощью наблюдателей за моделями Scout будет автоматически синхронизировать ваши поисковые индексы с вашими записями Eloquent.
Сейчас Scout поставляется с драйвером Algolia, однако написать свой драйвер довольно просто и вы можете дополнить Scout своей собственной реализацией поиска.
Установка
Сначала установите Scout через менеджер пакетов Composer:
shcomposer require laravel/scout
Затем добавьте PHPScoutServiceProvider
в массив PHPproviders
в файле настроек config/app.php:
Laravel\Scout\ScoutServiceProvider::class,
После регистрации сервис-провайдера Scout опубликуйте его конфигурацию с помощью Artisan-команды shvendor:publish
. Эта команда опубликует файл настроек scout.php в ваш каталог config:
shphp artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"
И наконец, добавьте типаж PHPLaravel\Scout\Searchable
в модель, которую хотите сделать доступной для поиска. Этот типаж зарегистрирует наблюдателя модели, чтобы синхронизировать модель с вашим драйвером поиска:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
}
Очередь
Вам нужно изучить настройку драйвера очереди перед использованием этой библиотеки, не смотря на то, что использовать очереди в Scout не обязательно. После запуска обработчика очереди Scout сможет ставить в очередь все операции синхронизации информации вашей модели с вашими поисковыми индексами, обеспечивая намного лучшее время отклика для веб-интерфейса вашего приложения.
После настройки драйвера очереди задайте значение PHPtrue
параметру PHPqueue
в файле настроек config/scout.php:
'queue' => true,
Условия для работы драйвера
Algolia
При использовании драйвера Algolia задайте ваши учётные данные Algolia (PHPid
и PHPsecret
) в файле настроек config/scout.php. После этого установите Algolia PHP SDK через менеджер пакетов Composer:
shcomposer require algolia/algoliasearch-client-php
Настройка
Настройка индексов модели
Каждая модель Eloquent синхронизируется с заданным поисковым «индексом», который содержит все записи для поиска этой модели. Другими словами, можно представить каждый индекс как таблицу MySQL. По умолчанию для каждой модели будет назначен индекс, совпадающий с именем «таблицы» модели. Обычно это множественная форма имени модели, но вы можете изменить индекс модели, переопределив для неё метод PHPsearchableAs()
:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* Получить имя индекса для модели.
*
* @return string
*/
public function searchableAs()
{
return 'posts_index';
}
}
Настройка данных для поиска
По умолчанию в индексе модели будут все её данные, аналогично результату PHPtoArray()
. Если вы хотите настроить то, какие данные будут синхронизироваться с поисковым индексом, переопределите метод модели PHPtoSearchableArray()
:
<?php
namespace App;
use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;
class Post extends Model
{
use Searchable;
/**
* Получить индексируемый массив данных для модели.
*
* @return array
*/
public function toSearchableArray()
{
$array = $this->toArray();
// Изменение массива...
return $array;
}
}
Индексирование
Групповой импорт
Если вы устанавливаете Scout в существующий проект, у вас уже могут быть записи БД, которые вам надо импортировать в ваш драйвер поиска. Scout предоставляет Artisan-команду import, которую можно использовать для импорта всех существующих записей в ваши поисковые индексы:
shphp artisan scout:import "App\Post"
Добавление записей
После добавления в модель типажа PHPLaravel\Scout\Searchable
вам остаётся только сохранить (PHPsave
) экземпляр модели, и она автоматически добавится в поисковый индекс. Если вы настроили Scout на использование очереди, то эта операция будет выполнена в фоне вашим обработчиком очереди:
$order = new App\Order;
// ...
$order->save();
Добавление через запрос
Если вы хотите добавить коллекцию моделей в свой поисковый индекс через запрос Eloquent, вы можете добавить метод PHPsearchable()
к запросу Eloquent. Метод PHPsearchable()
разделит на части результаты запроса и добавит записи в ваш поисковый индекс. Если вы настроили Scout на использование очередей, то все части будут добавлены в фоне обработчиками очереди:
// Добавление через запрос Eloquent...
App\Order::where('price', '>', 100)->searchable();
// Вы также можете добавить записи через отношения...
$user->orders()->searchable();
// Вы также можете добавить записи через коллекции...
$orders->searchable();
Метод PHPsearchable()
можно рассматривать как операцию «upsert». Другими словами, если запись модели уже в вашем индексе, она будет обновлена. А если её нет в поисковом индексе, то она будет добавлена в него.
Обновление записей
Для обновления модели, предназначенной для поиска, вам надо обновить только свойства экземпляра модели и сохранить (PHPsave
) модель в БД. Scout автоматически внесёт изменения в ваш поисковый индекс:
$order = App\Order::find(1);
// Обновить заказ...
$order->save();
Вы также можете использовать метод PHPsearchable()
на запросе Eloquent для обновления коллекции моделей. Если моделей нет в поисковом индексе, они будут созданы:
// Обновление через запрос Eloquent...
App\Order::where('price', '>', 100)->searchable();
// Вы также можете обновить через отношения...
$user->orders()->searchable();
// Вы также можете обновить через коллекции...
$orders->searchable();
Удаление записей
Для удаления записи из индекса просто удалите (PHPdelete
) модель из БД. Этот способ удаления совместим даже с мягко удаляемыми моделями:
$order = App\Order::find(1);
$order->delete();
Если вам не надо получать модель перед удалением записи, используйте метод PHPunsearchable()
на экземпляре запроса Eloquent или коллекции:
// Удаление через запрос Eloquent...
App\Order::where('price', '>', 100)->unsearchable();
// Также вы можете удалять через отношения...
$user->orders()->unsearchable();
// Также вы можете удалять через коллекции...
$orders->unsearchable();
Приостановка индексирования
Иногда бывает необходимо выполнить на модели группу операций Eloquent, при этом не синхронизируя данные модели с поисковым индексом. Это можно сделать методом PHPwithoutSyncingToSearch()
. Этот метод принимает единственное замыкание, который будет выполнен немедленно. Все операции на модели, сделанные в замыкании, не будут синхронизированы с индексом модели:
App\Order::withoutSyncingToSearch(function () {
// Выполнение действий над моделью...
});
Поиск
Вы можете начать поиск модели методом PHPsearch()
. Он принимает единственную строку, которая используется для поиска для поиска моделей. Затем вам надо добавить метод PHPget()
к поисковому запросу для получения моделей Eloquent, которые будут найдены по этому запросу:
$orders = App\Order::search('Star Trek')->get();
Поскольку поиск Scout возвращает коллекцию моделей Eloquent, вы можете вернуть результаты даже напрямую из маршрута или контроллера и они будут автоматически конвертированы в JSON:
use Illuminate\Http\Request;
Route::get('/search', function (Request $request) {
return App\Order::search($request->search)->get();
});
Условия WHERE
Scout позволяет добавлять простые условия «where» в ваши поисковые запросы. На данный момент эти условия поддерживают только базовые числовые сравнения на равенство и в основном полезны для ограничения поисковых запросов определённым ID. Поскольку поисковые индексы не являются реляционной БД, то более сложные условия «where» пока не поддерживаются:
$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();
Страничный вывод
Помимо получения коллекции моделей вы можете разделить результаты поиска на страницы методом PHPpaginate()
. Этот метод вернёт экземпляр PHPPaginator
, как и в случае страничного вывода обычного запроса Eloquent:
$orders = App\Order::search('Star Trek')->paginate();
Вы можете указать, сколько моделей необходимо размещать на одной странице, передав количество первым аргументом методу PHPpaginate()
:
$orders = App\Order::search('Star Trek')->paginate(15);
Когда вы получите результаты, вы можете отобразить их и вывести страничные ссылки с помощью Blade, как и в случае страничного вывода обычного запроса Eloquent:
<div class="container">
@foreach ($orders as $order)
{{ $order->price }}
@endforeach
</div>
{{ $orders->links() }}
Пользовательские движки
Создание движка
Если ни один из встроенных поисковых движков Scout вам не подходит, вы можете написать свой собственный движок и зарегистрировать его в Scout. Ваш движок должен наследовать абстрактный класс PHPLaravel\Scout\Engines\Engine
. Этот абстрактный класс содержит пять методов, которые должен реализовать ваш движок:
use Laravel\Scout\Builder;
abstract public function update($models);
abstract public function delete($models);
abstract public function search(Builder $builder);
abstract public function paginate(Builder $builder, $perPage, $page);
abstract public function map($results, $model);
Вам может быть полезно посмотреть на реализацию этих методов в классе PHPLaravel\Scout\Engines\AlgoliaEngine
. Этот класс предоставит вам хорошую отправную точку для изучения того, как реализуется каждый из этих методов.
Регистрация движка
После создания своего движка вы можете зарегистрировать его в Scout с помощью метода PHPextend()
менеджера движков Scout. Вам надо вызвать метод PHPextend()
из метода PHPboot()
вашего PHPAppServiceProvider
или любого другого сервис-провайдера в вашем приложении. Например, если вы создали PHPMySqlSearchEngine
, зарегистрируйте его так:
use Laravel\Scout\EngineManager;
/**
* Начальная загрузка всех сервисов приложения.
*
* @return void
*/
public function boot()
{
resolve(EngineManager::class)->extend('mysql', function () {
return new MySqlSearchEngine;
});
}
После регистрации движка вы можете указать его в качестве драйвера (driver) Scout по умолчанию в файле настроек config/scout.php:
'driver' => 'mysql',
Комментарии (2)
спасибо.
А Алголия это фри драйвер?
Странный вопрос) Algolia это компания основной товар которой это предоставление своего сервиса по модели SaaS (software as a service),
У них есть бесплатный тариф с лимитом в 10K записей/100K операций этого достаточно что бы потестировать и разобраться, а некоторым и вовсе для реального проекта достаточно)
Драйвер алголии бесплатный, а вот сервис платный
Можно использовать поисковый движок elasticsearch, он бесплатный и довольно шустрый