Вступление

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

В настоящее время разведчик поставляется с водителем Алголии ; однако написание пользовательских драйверов очень просто, и вы можете расширить Scout своими собственными поисковыми реализациями.

 

Установка

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

composer require laravel/scout

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

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 ставить в очередь все операции, которые синхронизируют информацию о вашей модели с вашими поисковыми индексами, обеспечивая намного лучшее время отклика для веб-интерфейса вашего приложения.

После того как вы настроили драйвер очереди, установите значение queueпараметра в вашем файле конфигурации :config/scout.phptrue

'queue' => true,

 

Необходимые условия для водителя

Algolia

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

composer require algolia/algoliasearch-client-php:^2.2

 

Конфигурация

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

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

<?php

namespace App;

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

class Post extends Model
{
    use Searchable;

    /**
     * Get the index name for the model.
     *
     * @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;

    /**
     * Get the indexable data array for the model.
     *
     * @return array
     */
    public function toSearchableArray()
    {
        $array = $this->toArray();

        // Customize array...

        return $array;
    }
}

 

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

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

<?php

namespace App;

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

class User extends Model
{
    use Searchable;

    /**
     * Get the value used to index the model.
     *
     * @return mixed
     */
    public function getScoutKey()
    {
        return $this->email;
    }
}

 

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

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

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

php artisan scout:import "App\Post"

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

php artisan scout:flush "App\Post"

 

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

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

$order = new App\Order;

// ...

$order->save();

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

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

// Adding via Eloquent query...
App\Order::where('price', '>', 100)->searchable();

// You may also add records via relationships...
$user->orders()->searchable();

// You may also add records via collections...
$orders->searchable();

Этот searchableметод можно считать операцией "upsert". Другими словами, если запись модели уже есть в вашем индексе, она будет обновлена. Если он не существует в поисковом индексе, он будет добавлен в индекс.

 

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

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

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

// Update the order...

$order->save();

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

// Updating via Eloquent query...
App\Order::where('price', '>', 100)->searchable();

// You may also update via relationships...
$user->orders()->searchable();

// You may also update via collections...
$orders->searchable();

 

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

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

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

$order->delete();

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

// Removing via Eloquent query...
App\Order::where('price', '>', 100)->unsearchable();

// You may also remove via relationships...
$user->orders()->unsearchable();

// You may also remove via collections...
$orders->unsearchable();

 

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

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

App\Order::withoutSyncingToSearch(function () {
    // Perform model actions...
});

 

Экземпляры модели с условным поиском

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

public function shouldBeSearchable()
{
    return $this->isPublished();
}

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

// Will respect "shouldBeSearchable"...
App\Order::where('price', '>', 100)->searchable();

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

$order->save();

// Will override "shouldBeSearchable"...
$orders->searchable();

$order->searchable();

 

Поиск

Вы можете начать поиск модели, используя 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методе модели . Тем не менее, вы можете использовать withinметод для указания пользовательского индекса, который следует искать вместо:

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

 

Где пункты

Scout позволяет добавлять простые предложения "где" к вашим поисковым запросам. В настоящее время эти пункты поддерживают только базовые проверки числового равенства и в первую очередь полезны для определения области поисковых запросов по идентификатору клиента. Поскольку поисковый индекс не является реляционной базой данных, более продвинутые предложения "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() }}

 

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

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

'soft_delete' => true,

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

// Include trashed records when retrieving results...
$orders = App\Order::search('Star Trek')->withTrashed()->get();

// Only include trashed records when retrieving results...
$orders = App\Order::search('Star Trek')->onlyTrashed()->get();

Когда мягко удаленная модель будет окончательно удалена с помощью forceDelete, Scout автоматически удалит ее из поискового индекса.

 

Настройка поиска двигателя

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

use Algolia\AlgoliaSearch\SearchIndex;

App\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();

 

Таможенные двигатели

Написание двигателя

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

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

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

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

use Laravel\Scout\EngineManager;

/**
 * Bootstrap any application services.
 *
 * @return void
 */
public function boot()
{
    resolve(EngineManager::class)->extend('mysql', function () {
        return new MySqlSearchEngine;
    });
}

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

'driver' => 'mysql',

 

Макросы строителя

Если вы хотите определить пользовательский метод компоновщика, вы можете использовать macroметод в классе. Как правило, «макросы» должны быть определены в методе поставщика услуг :Laravel\Scout\Builder boot

<?php

namespace App\Providers;

use Laravel\Scout\Builder;
use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Response;

class ScoutMacroServiceProvider extends ServiceProvider
{
    /**
     * Register the application's scout macros.
     *
     * @return void
     */
    public function boot()
    {
        Builder::macro('count', function () {
            return $this->engine->getTotalCount(
                $this->engine()->search($this)
            );
        });
    }
}

macroФункция принимает имя в качестве первого аргумента, и его закрытия в качестве второго. Закрытие макроса будет выполнено при вызове имени макроса из реализации:Laravel\Scout\Builder

App\Order::search('Star Trek')->count();