Идёт обновление сайта. Несколько дней возможны сбои в оформлении и переводах. Документация работает — если страница выглядит сломанной, обновите её позже.

Документация
L Laravel L intervention/image
Войти

Laravel Scout

10.x 7 мар 2026 г.

#Введение

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

В настоящее время Scout поставляется с драйверами для Algolia, Meilisearch, Typesense и MySQL / PostgreSQL (database). Кроме того, Scout включает драйвер "collection", предназначенный для локальной разработки и не требующий внешних зависимостей или сторонних сервисов. Также написание собственных драйверов просто, и вы можете расширять Scout своими реализациями поиска.

#Установка

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

composer require laravel/scout

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

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

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

<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;
}

#Очереди

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

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

'queue' => true,

Даже если опция queue установлена в false, важно помнить, что некоторые драйверы Scout, такие как Algolia и Meilisearch, всегда индексируют записи асинхронно. Это значит, что хотя операция индексации завершилась в вашем приложении Laravel, сам поисковый движок может не сразу отразить новые или обновлённые записи.

Чтобы указать соединение и очередь, которые будут использоваться задачами Scout, можно определить опцию queue как массив:

'queue' => [
    'connection' => 'redis',
    'queue' => 'scout'
],

Разумеется, если вы настраиваете соединение и очередь для задач Scout, необходимо запустить воркер очереди для обработки задач на этом соединении и очереди:

php artisan queue:work redis --queue=scout

#Требования к драйверам

#Algolia

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

composer require algolia/algoliasearch-client-php

#Meilisearch

Meilisearch — это очень быстрый и открытый поисковый движок. Если вы не знаете, как установить Meilisearch на локальную машину, вы можете использовать Laravel Sail — официально поддерживаемую среду разработки на Docker.

При использовании драйвера Meilisearch необходимо установить PHP SDK Meilisearch через менеджер пакетов Composer:

composer require meilisearch/meilisearch-php http-interop/http-factory-guzzle

Затем установите переменную окружения SCOUT_DRIVER, а также укажите ваши учетные данные host и key Meilisearch в файле .env вашего приложения:

SCOUT_DRIVER=meilisearch
MEILISEARCH_HOST=http://127.0.0.1:7700
MEILISEARCH_KEY=masterKey

Для получения дополнительной информации о Meilisearch обратитесь к документации Meilisearch.

Кроме того, убедитесь, что вы установили версию meilisearch/meilisearch-php, совместимую с вашей версией бинарного файла Meilisearch, ознакомившись с документацией Meilisearch по совместимости бинарников.

Внимание

При обновлении Scout в приложении, использующем Meilisearch, всегда проверяйте дополнительные изменения, нарушающие совместимость самого сервиса Meilisearch.

#Typesense

Typesense — это очень быстрый, открытый поисковый движок, поддерживающий поиск по ключевым словам, семантический поиск, геопоиск и векторный поиск.

Вы можете развернуть Typesense самостоятельно или использовать Typesense Cloud.

Чтобы начать использовать Typesense с Scout, установите PHP SDK Typesense через менеджер пакетов Composer:

composer require typesense/typesense-php

Затем задайте переменную окружения SCOUT_DRIVER, а также хост Typesense и учётные данные API-ключа в файле .env вашего приложения:

SCOUT_DRIVER=typesense
TYPESENSE_API_KEY=masterKey
TYPESENSE_HOST=localhost

При необходимости вы также можете указать порт, путь и протокол вашей установки:

TYPESENSE_PORT=8108
TYPESENSE_PATH=
TYPESENSE_PROTOCOL=http

Дополнительные настройки и определения схем для коллекций Typesense можно найти в файле конфигурации config/scout.php вашего приложения. Для получения дополнительной информации обратитесь к документации Typesense.

#Подготовка данных для хранения в Typesense

При использовании Typesense ваша индексируемая модель должна определить метод toSearchableArray, который приводит первичный ключ модели к строке, а дату создания — к UNIX-метке времени:

/**
 * Получить массив данных для индексации модели.
 *
 * @return array<string, mixed>
 */
public function toSearchableArray()
{
    return array_merge($this->toArray(),[
        'id' => (string) $this->id,
        'created_at' => $this->created_at->timestamp,
    ]);
}

Вы также должны определить схемы коллекций Typesense в файле config/scout.php вашего приложения. Схема коллекции описывает типы данных каждого поля, доступного для поиска через Typesense. Для получения информации обо всех доступных параметрах схемы обратитесь к документации Typesense.

Если вам нужно изменить схему коллекции Typesense после её определения, вы можете либо выполнить команды scout:flush и scout:import, которые удалят все существующие индексированные данные и пересоздадут схему, либо использовать API Typesense для изменения схемы коллекции без удаления индексированных данных.

Если ваша индексируемая модель поддерживает мягкое удаление, вы должны определить поле __soft_deleted в соответствующей схеме Typesense модели в файле конфигурации config/scout.php вашего приложения:

User::class => [
    'collection-schema' => [
        'fields' => [
            // ...
            [
                'name' => '__soft_deleted',
                'type' => 'int32',
                'optional' => true,
            ],
        ],
    ],
],

#Динамические параметры поиска

Typesense позволяет динамически изменять ваши параметры поиска при выполнении операции поиска через метод options:

use App\Models\Todo;

Todo::search('Groceries')->options([
    'query_by' => 'title, description'
])->get();

#Настройка

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

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

<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;

    /**
     * Получить имя индекса, связанного с моделью.
     */
    public function searchableAs(): string
    {
        return 'posts_index';
    }
}

#Настройка индексируемых данных

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

<?php

namespace App\Models;

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

class Post extends Model
{
    use Searchable;

    /**
     * Получить массив данных для индексации модели.
     *
     * @return array<string, mixed>
     */
    public function toSearchableArray(): array
    {
        $array = $this->toArray();

        // Настройте массив данных...

        return $array;
    }
}

Некоторые поисковые движки, такие как Meilisearch, выполняют операции фильтрации (>, < и т.д.) только для данных правильного типа. Поэтому при использовании таких движков и настройке индексируемых данных следует убедиться, что числовые значения приведены к нужному типу:

public function toSearchableArray()
{
    return [
        'id' => (int) $this->id,
        'name' => $this->name,
        'price' => (float) $this->price,
    ];
}

#Настройка фильтруемых данных и параметров индекса (Meilisearch)

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

Фильтруемые атрибуты — это те, по которым вы планируете фильтровать при вызове метода where Scout, а сортируемые — по которым будете сортировать при вызове orderBy. Чтобы определить настройки индекса, отредактируйте раздел index-settings в конфигурации meilisearch в файле scout вашего приложения:

use App\Models\User;
use App\Models\Flight;

'meilisearch' => [
    'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
    'key' => env('MEILISEARCH_KEY', null),
    'index-settings' => [
        User::class => [
            'filterableAttributes'=> ['id', 'name', 'email'],
            'sortableAttributes' => ['created_at'],
            // Другие поля настроек...
        ],
        Flight::class => [
            'filterableAttributes'=> ['id', 'destination'],
            'sortableAttributes' => ['updated_at'],
        ],
    ],
],

Если модель, лежащая в основе индекса, поддерживает мягкое удаление и включена в массив index-settings, Scout автоматически добавит поддержку фильтрации по мягко удалённым моделям для этого индекса. Если у вас нет других фильтруемых или сортируемых атрибутов для такой модели, вы можете просто добавить пустую запись в массив index-settings для этой модели:

'index-settings' => [
    Flight::class => []
],

После настройки параметров индекса вашего приложения необходимо выполнить Artisan-команду scout:sync-index-settings. Эта команда сообщит Meilisearch о текущих настройках индекса. Для удобства вы можете включить эту команду в процесс деплоя:

php artisan scout:sync-index-settings

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

По умолчанию Scout использует первичный ключ модели в качестве уникального идентификатора, сохраняемого в поисковом индексе. Если нужно изменить это поведение, можно переопределить методы getScoutKey и getScoutKeyName в модели:

<?php

namespace App\Models;

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

class User extends Model
{
    use Searchable;

    /**
     * Получить значение, используемое для индексации модели.
     */
    public function getScoutKey(): mixed
    {
        return $this->email;
    }

    /**
     * Получить имя ключа, используемого для индексации модели.
     */
    public function getScoutKeyName(): mixed
    {
        return 'email';
    }
}

#Настройка поисковых движков для каждой модели

При поиске Scout обычно использует поисковой движок по умолчанию, указанный в конфигурации scout вашего приложения. Однако движок для конкретной модели можно изменить, переопределив метод searchableUsing в модели:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Laravel\Scout\Engines\Engine;
use Laravel\Scout\EngineManager;
use Laravel\Scout\Searchable;

class User extends Model
{
    use Searchable;

    /**
     * Получить движок, используемый для индексации модели.
     */
    public function searchableUsing(): Engine
    {
        return app(EngineManager::class)->engine('meilisearch');
    }
}

#Идентификация пользователей

Scout также позволяет автоматически идентифицировать пользователей при использовании Algolia. Связывание аутентифицированного пользователя с операциями поиска может быть полезно для просмотра аналитики поиска в панели Algolia. Вы можете включить идентификацию пользователей, установив переменную окружения SCOUT_IDENTIFY в true в файле .env вашего приложения:

SCOUT_IDENTIFY=true

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

#Движки базы данных / коллекций

#Движок базы данных

Внимание

Движок базы данных в настоящее время поддерживает MySQL и PostgreSQL.

Если ваше приложение работает с базами данных малого или среднего размера или имеет небольшую нагрузку, вам может быть удобнее начать с движка "database" Scout. Этот движок использует условия "where like" и полнотекстовые индексы для фильтрации результатов из вашей существующей базы данных, чтобы определить подходящие результаты поиска для вашего запроса.

Чтобы использовать движок базы данных, просто установите значение переменной окружения SCOUT_DRIVER в database или укажите драйвер database напрямую в конфигурации scout вашего приложения:

SCOUT_DRIVER=database

После указания движка базы данных в качестве предпочтительного драйвера необходимо настроить индексируемые данные. Затем вы можете начать выполнять поисковые запросы по вашим моделям. Индексация поискового движка, например, необходимая для заполнения индексов Algolia, Meilisearch или Typesense, при использовании движка базы данных не требуется.

#Настройка стратегий поиска в базе данных

По умолчанию движок базы данных выполняет запрос "where like" по каждому атрибуту модели, который вы настроили как индексируемый. Однако в некоторых случаях это может привести к плохой производительности. Поэтому стратегию поиска движка базы данных можно настроить так, чтобы некоторые указанные столбцы использовали полнотекстовый поиск или только условия "where like" для поиска по префиксам строк (example%), а не по всему содержимому строки (%example%).

Для определения такого поведения можно назначить PHP-атрибуты методу toSearchableArray вашей модели. Любые столбцы, для которых не задано дополнительное поведение поиска, будут использовать стратегию "where like" по умолчанию:

use Laravel\Scout\Attributes\SearchUsingFullText;
use Laravel\Scout\Attributes\SearchUsingPrefix;

/**
 * Получить массив данных для индексации модели.
 *
 * @return array<string, mixed>
 */
#[SearchUsingPrefix(['id', 'email'])]
#[SearchUsingFullText(['bio'])]
public function toSearchableArray(): array
{
    return [
        'id' => $this->id,
        'name' => $this->name,
        'email' => $this->email,
        'bio' => $this->bio,
    ];
}
Внимание

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

#Движок коллекций

Хотя вы можете использовать поисковые движки Algolia, Meilisearch или Typesense во время локальной разработки, вам может быть удобнее начать с движка "collection". Движок коллекций использует условия "where" и фильтрацию коллекций для результатов из вашей существующей базы данных, чтобы определить подходящие результаты поиска для вашего запроса. При использовании этого движка индексация моделей не требуется, так как они просто извлекаются из локальной базы данных.

Чтобы использовать движок коллекций, просто установите значение переменной окружения SCOUT_DRIVER в collection или укажите драйвер collection напрямую в конфигурации scout вашего приложения:

SCOUT_DRIVER=collection

После указания драйвера коллекций в качестве предпочтительного драйвера вы можете начать выполнять поисковые запросы по вашим моделям. Индексация поискового движка, например, необходимая для заполнения индексов Algolia, Meilisearch или Typesense, при использовании движка коллекций не требуется.

#Отличия от движка базы данных

На первый взгляд движки "database" и "collection" довольно похожи. Оба взаимодействуют напрямую с вашей базой данных для получения результатов поиска. Однако движок коллекций не использует полнотекстовые индексы или условия LIKE для поиска совпадающих записей. Вместо этого он извлекает все возможные записи и использует помощник Laravel Str::is для определения, содержится ли поисковая строка в значениях атрибутов модели.

Движок коллекций является самым переносимым поисковым движком, так как работает со всеми реляционными базами данных, поддерживаемыми Laravel (включая SQLite и SQL Server); однако он менее эффективен, чем движок базы данных Scout.

#Индексация

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

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

php artisan scout:import "App\Models\Post"

Команда flush может использоваться для удаления всех записей модели из ваших поисковых индексов:

php artisan scout:flush "App\Models\Post"

#Изменение запроса импорта

Если вы хотите изменить запрос, используемый для получения всех моделей при пакетном импорте, вы можете определить метод makeAllSearchableUsing в вашей модели. Это хорошее место для добавления жадной загрузки связей, если это необходимо перед импортом моделей:

use Illuminate\Database\Eloquent\Builder;

/**
 * Изменить запрос, используемый для получения моделей при массовом индексировании.
 */
protected function makeAllSearchableUsing(Builder $query): Builder
{
    return $query->with('author');
}
Внимание

Метод makeAllSearchableUsing может быть неприменим при использовании очередей для пакетного импорта моделей. Связи не восстанавливаются при обработке коллекций моделей в заданиях.

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

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

use App\Models\Order;

$order = new Order;

// ...

$order->save();

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

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

use App\Models\Order;

Order::where('price', '>', 100)->searchable();

Вы также можете вызвать метод searchable на экземпляре отношения Eloquent:

$user->orders()->searchable();

Или, если у вас уже есть коллекция моделей Eloquent в памяти, вызовите метод searchable на коллекции, чтобы добавить экземпляры моделей в соответствующий индекс:

$orders->searchable();
Примечание

Метод searchable можно рассматривать как операцию "upsert". Другими словами, если запись модели уже есть в индексе, она будет обновлена. Если её нет — добавлена.

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

Чтобы обновить индексируемую модель, достаточно изменить свойства экземпляра модели и вызвать save. Scout автоматически сохранит изменения в поисковом индексе:

use App\Models\Order;

$order = Order::find(1);

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

$order->save();

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

Order::where('price', '>', 100)->searchable();

Если вы хотите обновить записи индекса для всех моделей в отношении, вызовите метод searchable на экземпляре отношения:

$user->orders()->searchable();

Или, если у вас уже есть коллекция моделей Eloquent в памяти, вызовите метод searchable на коллекции, чтобы обновить экземпляры моделей в соответствующем индексе:

$orders->searchable();

#Изменение записей перед импортом

Иногда нужно подготовить коллекцию моделей перед индексированием. Например, можно жадно загрузить связь, чтобы данные связи эффективно добавлялись в индекс. Для этого определите метод makeSearchableUsing в соответствующей модели:

use Illuminate\Database\Eloquent\Collection;

/**
 * Изменить коллекцию моделей перед индексированием.
 */
public function makeSearchableUsing(Collection $models): Collection
{
    return $models->load('author');
}

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

Чтобы удалить запись из индекса, вы можете просто delete модель в базе данных. Это можно сделать даже если вы используете модели с мягким удалением:

use App\Models\Order;

$order = Order::find(1);

$order->delete();

Если вы не хотите загружать модель перед удалением записи, можно использовать метод unsearchable на запросе Eloquent:

Order::where('price', '>', 100)->unsearchable();

Если нужно удалить записи индекса для всех моделей в отношении, вызовите метод unsearchable на экземпляре отношения:

$user->orders()->unsearchable();

Или, если у вас уже есть коллекция моделей Eloquent в памяти, вызовите метод unsearchable на коллекции, чтобы удалить экземпляры моделей из соответствующего индекса:

$orders->unsearchable();

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

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

use App\Models\Order;

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

#Условно индексируемые экземпляры моделей

Иногда нужно индексировать модель только при определённых условиях. Например, предположим, что у вас есть модель App\Models\Post, которая может находиться в одном из двух состояний: "черновик" и "опубликована". Вы можете разрешить индексировать только "опубликованные" посты. Для этого определите метод shouldBeSearchable в модели:

/**
 * Определить, должна ли модель быть индексируемой.
 */
public function shouldBeSearchable(): bool
{
    return $this->isPublished();
}

Метод shouldBeSearchable применяется только при работе с моделями через методы save и create, запросы или отношения. Прямое индексирование моделей или коллекций через метод searchable игнорирует результат метода shouldBeSearchable.

Внимание

Метод shouldBeSearchable не применяется при использовании движка "database" Scout, так как все индексируемые данные всегда хранятся в базе данных. Для аналогичного поведения с движком базы данных следует использовать условия where.

#Поиск

Вы можете начать поиск по модели с помощью метода search. Метод принимает строку, которая будет использоваться для поиска по моделям. Затем вызовите метод get для получения моделей Eloquent, соответствующих поисковому запросу:

use App\Models\Order;

$orders = Order::search('Star Trek')->get();

Поскольку поиск Scout возвращает коллекцию моделей Eloquent, вы можете напрямую возвращать результаты из маршрута или контроллера, и они автоматически будут преобразованы в JSON:

use App\Models\Order;
use Illuminate\Http\Request;

Route::get('/search', function (Request $request) {
    return Order::search($request->search)->get();
});

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

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

#Пользовательские индексы

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

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

#Условия where

Scout позволяет добавлять простые условия "where" к поисковым запросам. В настоящее время эти условия поддерживают только базовые проверки числового равенства и в основном полезны для ограничения поиска по идентификатору владельца:

use App\Models\Order;

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

Кроме того, метод whereIn можно использовать для проверки, что значение столбца содержится в заданном массиве:

$orders = Order::search('Star Trek')->whereIn(
    'status', ['open', 'paid']
)->get();

Метод whereNotIn проверяет, что значение столбца не содержится в заданном массиве:

$orders = Order::search('Star Trek')->whereNotIn(
    'status', ['closed']
)->get();

Поскольку поисковый индекс не является реляционной базой данных, более сложные условия "where" в настоящее время не поддерживаются.

Внимание

Если ваше приложение использует Meilisearch, необходимо настроить фильтруемые атрибуты перед использованием условий "where" Scout.

#Пагинация

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

use App\Models\Order;

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

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

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

После получения результатов вы можете отобразить их и вывести ссылки пагинации с помощью Blade, как при пагинации обычного запроса Eloquent:

<div class="container">
    @foreach ($orders as $order)
        {{ $order->price }}
    @endforeach
</div>

{{ $orders->links() }}

Разумеется, если вы хотите получить результаты пагинации в формате JSON, вы можете вернуть экземпляр пагинатора напрямую из маршрута или контроллера:

use App\Models\Order;
use Illuminate\Http\Request;

Route::get('/orders', function (Request $request) {
    return Order::search($request->input('query'))->paginate(15);
});
Внимание

Поскольку поисковые движки не учитывают глобальные скоупы моделей Eloquent, не следует использовать глобальные скоупы в приложениях с пагинацией Scout. Либо необходимо воссоздавать ограничения глобальных скоупов при поиске через Scout.

#Мягкое удаление

Если ваши индексируемые модели используют мягкое удаление и вам нужно искать по мягко удалённым моделям, установите опцию soft_delete в файле конфигурации config/scout.php в true:

'soft_delete' => true,

При значении этой опции true Scout не удаляет мягко удалённые модели из поискового индекса. Вместо этого в индексируемой записи устанавливается скрытый атрибут __soft_deleted. Затем вы можете использовать методы withTrashed или onlyTrashed для получения мягко удалённых записей при поиске:

use App\Models\Order;

// Включить мягко удалённые записи при получении результатов...
$orders = Order::search('Star Trek')->withTrashed()->get();

// Включить только мягко удалённые записи при получении результатов...
$orders = Order::search('Star Trek')->onlyTrashed()->get();
Примечание

При окончательном удалении модели методом forceDelete Scout автоматически удалит её из поискового индекса.

#Настройка поисковых запросов движка

Если нужно выполнить расширенную настройку поведения поиска движка, можно передать замыкание вторым аргументом методу search. Например, вы можете использовать этот callback для добавления геолокационных данных в параметры поиска перед передачей запроса в Algolia:

use Algolia\AlgoliaSearch\SearchIndex;
use App\Models\Order;

Order::search(
    'Star Trek',
    function (SearchIndex $algolia, string $query, array $options) {
        $options['body']['query']['bool']['filter']['geo_distance'] = [
            'distance' => '1000km',
            'location' => ['lat' => 36, 'lon' => 111],
        ];

        return $algolia->search($query, $options);
    }
)->get();

#Настройка запроса к результатам Eloquent

После того как Scout получает список совпадающих моделей Eloquent из поискового движка вашего приложения, Eloquent используется для получения всех совпадающих моделей по их первичным ключам. Вы можете настроить этот запрос, вызвав метод query. Метод query принимает замыкание, которое получит экземпляр конструктора запросов Eloquent в качестве аргумента:

use App\Models\Order;
use Illuminate\Database\Eloquent\Builder;

$orders = Order::search('Star Trek')
    ->query(fn (Builder $query) => $query->with('invoices'))
    ->get();

Поскольку этот callback вызывается после получения моделей из поискового движка, метод query не следует использовать для "фильтрации" результатов. Для этого лучше использовать условия where Scout.

#Пользовательские движки

#Написание движка

Если ни один из встроенных поисковых движков 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 mapIds($results);
abstract public function map(Builder $builder, $results, $model);
abstract public function getTotalCount($results);
abstract public function flush($model);

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

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

После написания собственного движка вы можете зарегистрировать его в Scout с помощью метода extend менеджера движков Scout. Менеджер движков можно получить из контейнера сервисов Laravel. Вызовите метод extend в методе boot вашего класса App\Providers\AppServiceProvider или любого другого сервис-провайдера вашего приложения:

use App\ScoutExtensions\MySqlSearchEngine;
use Laravel\Scout\EngineManager;

/**
 * Загрузить сервисы приложения.
 */
public function boot(): void
{
    resolve(EngineManager::class)->extend('mysql', function () {
        return new MySqlSearchEngine;
    });
}

После регистрации движка вы можете указать его в качестве driver по умолчанию для Scout в конфигурационном файле приложения config/scout.php:

'driver' => 'mysql',