Поддержите проект сделав пожертвование.
Поделитесь своим кодом и идеями!
Поделитесь своим кодом и идеями!

Laravel Scout

Вы просматриваете документ для прошлой версии.
Рассмотрите возможность обновления вашего проекта до актуальной версии 11.x. Почему это важно?

Введение

Laravel Scout предоставляет простое решение на основе драйверов для добавления полнотекстового поиска в ваши Eloquent-модели. С помощью наблюдателей за моделями Scout будет автоматически синхронизировать ваши поисковые индексы с вашими записями Eloquent.

Сейчас Scout поставляется с драйвером Algolia; однако, написать свой драйвер довольно просто и вы можете дополнить Scout своей собственной реализацией поиска.

Установка

Сначала установите Scout через менеджер пакетов Composer:

composer require laravel/scout

Затем добавьте ScoutServiceProvider в массив providers вашего конфига config/app.php:

Laravel\Scout\ScoutServiceProvider::class,

После регистрации сервис-провайдера Scout опубликуйте его конфигурацию с помощью Artisan-команды vendor:publish. Эта команда опубликует файл настроек scout.php в ваш каталог config:

php artisan vendor:publish --provider="Laravel\Scout\ScoutServiceProvider"

И наконец, добавьте трейт Laravel\Scout\Searchable в модель, которую хотите сделать доступной для поиска. Этот трейт зарегистрирует наблюдателя модели, чтобы синхронизировать модель с вашим драйвером поиска:

<?php

namespace App;

use Laravel\Scout\Searchable;
use Illuminate\Database\Eloquent\Model;

class Post extends Model
{
    use Searchable;
}

Очередь

Вам нужно изучить настройку драйвера очереди перед использованием этой библиотеки, не смотря на то, что использовать очереди в Scout не обязательно. После запуска обработчика очереди Scout сможет ставить в очередь все операции синхронизации информации вашей модели с вашими поисковыми индексами, обеспечивая намного лучшее время отклика для веб-интерфейса вашего приложения.

После настройки драйвера очереди задайте значение true параметру queue в конфиге config/scout.php:

'queue' => true,

Условия для работы драйвера

Algolia

При использовании драйвера Algolia задайте ваши учётные данные Algolia id и secret в своем конфиге config/scout.php. После этого установите Algolia PHP SDK через менеджер пакетов Composer:

composer require algolia/algoliasearch-client-php

Настройка

Настройка индексов модели

Каждая модель Eloquent синхронизируется с заданным поисковым “индексом”, который содержит все записи для поиска этой модели. Другими словами, можно представить каждый индекс как таблицу MySQL. По-умолчанию для каждой модели будет назначен индекс, совпадающий с именем “таблицы” модели. Как правило, это множественная форма имени модели, но вы можете изменить индекс модели, переопределив для неё метод searchableAs:

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

Настройка данных для поиска

По-умолчанию в индексе модели будут все её данные, аналогично результату toArray. Если вы хотите настроить то, какие данные будут синхронизироваться с поисковым индексом, переопределите метод модели toSearchableArray:

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

        // Customize array...

        return $array;
    }
}

Индексирование

Пакетный импорт

Если вы устанавливаете Scout в существующий проект, у вас уже могут быть записи БД, которые вам надо импортировать в ваш драйвер поиска. Scout предоставляет Artisan-команду import, которую можно использовать для импорта всех существующих записей в ваши поисковые индексы:

php artisan scout:import "App\Post"

Добавление записей

После добавления в модель типажа Laravel\Scout\Searchable вам остаётся только сохранить (save) экземпляр модели, и она автоматически добавится в поисковый индекс. Если вы настроили Scout на использование очередей, то эта операция будет выполнена в фоне вашим обработчиком очереди:

$order = new App\Order;

// ...

$order->save();

Добавление через запрос

Если вы хотите добавить коллекцию моделей в свой поисковый индекс через запрос Eloquent, вы можете добавить метод searchable к запросу Eloquent. Метод searchable разделит на части результаты запроса и добавит записи в ваш поисковый индекс. Если вы настроили Scout на использование очередей, то все части будут добавлены в фоне обработчиками очереди:

// Добавление через запрос Eloquent...
App\Order::where('price', '>', 100)->searchable();

// Вы также можете добавить записи через отношения...
$user->orders()->searchable();

// Вы также можете добавить записи через коллекции...
$orders->searchable();

Метод searchable можно рассматривать как операцию “upsert” (обновить или вставить). Другими словами, если запись модели уже в вашем индексе, она будет обновлена. А если её нет в поисковом индексе, то она будет добавлена в него.

Обновление записей

Для обновления модели, предназначенной для поиска, вам надо обновить только свойства экземпляра модели и сохранить (save) модель в БД. Scout автоматически внесёт изменения в ваш поисковый индекс:

$order = App\Order::find(1);

// Обновить заказ...

$order->save();

Вы также можете использовать метод searchable на запросе Eloquent для обновления коллекции моделей. Если моделей нет в поисковом индексе, они будут созданы:

// Обновление через запрос Eloquent...
App\Order::where('price', '>', 100)->searchable();

// Вы также можете обновить через отношения...
$user->orders()->searchable();

// Вы также можете обновить через коллекции...
$orders->searchable();

Удаление записей

Для удаления записи из индекса просто удалите (delete) модель из БД. Этот способ удаления совместим даже с мягко удаляемыми моделями:

$order = App\Order::find(1);

$order->delete();

Если вам не надо получать модель перед удалением записи, используйте метод unsearchable на экземпляре запроса Eloquent или коллекции:

// Удаление через запрос Eloquent...
App\Order::where('price', '>', 100)->unsearchable();

// Также вы можете удалять через отношения...
$user->orders()->unsearchable();

// Также вы можете удалять через коллекции...
$orders->unsearchable();

Приостановка индексирования

Иногда бывает необходимо выполнить на модели группу операций Eloquent, при этом не синхронизируя данные модели с поисковым индексом. Это можно сделать методом withoutSyncingToSearch. Этот метод принимает единственную анонимную функцию, которая будет выполнен немедленно. Все операции на модели, сделанные в функции, не будут синхронизированы с индексом модели:

App\Order::withoutSyncingToSearch(function () {
    // Выполнение действий над моделью...
});

Поиск

Вы можете начать поиск модели методом search. Он принимает единственную строку, которая используется для поиска для поиска моделей. Затем вам надо добавить метод get к поисковому запросу для получения моделей 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();
});

Если вы бы хотели получить необработанные результаты прежде, чем они будут сконвертированы в модели Eloquent, следует использовать метод raw:

$orders = App\Order::search('Star Trek')->raw();

Поисковые запросы, как правило, будут выполняться в индексе, указываемом методом модели searchableAs method. Однако, вы можете использовать метод within, чтобы указать собственный индекс:

$orders = App\Order::search('Star Trek')
    ->within('tv_shows_popularity_desc')
    ->get();

Условия Where

Scout позволяет добавлять простые условия “where” в ваши поисковые запросы. На данный момент эти условия поддерживают только базовые числовые сравнения на равенство и в основном полезны для ограничения поисковых запросов определённым ID. Поскольку поисковые индексы не являются реляционной БД, то более сложные условия “where” пока не поддерживаются:

$orders = App\Order::search('Star Trek')->where('user_id', 1)->get();

Страничный вывод

Помимо получения коллекции моделей вы можете разделить результаты поиска на страницы методом paginate. Этот метод вернёт экземпляр Paginator, как и в случае страничного вывода обычного запроса Eloquent:

$orders = App\Order::search('Star Trek')->paginate();

Вы можете указать, сколько моделей необходимо размещать на одной странице, передав количество первым аргументом методу paginate:

$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. Ваш движок должен наследовать абстрактный класс Laravel\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);

Вам может быть полезно посмотреть на реализацию этих методов в классе Laravel\Scout\Engines\AlgoliaEngine. Этот класс предоставит вам хорошую отправную точку для изучения того, как реализуется каждый из этих методов.

Регистрация движка

После создания своего движка вы можете зарегистрировать его в Scout с помощью метода extend менеджера движков Scout. Вам надо вызвать метод extend из метода boot вашего AppServiceProvider или любого другого сервис-провайдера в вашем приложении. Например, если вы создали MySqlSearchEngine, зарегистрируйте его так:

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