WDN

MeiliSearch и Laravel

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

Установка Meilisearch

Под Windows всё просто: заходим на страницу проекта в проекта в GitHub, находим последнюю сборку с именем вроде meilisearch-windows-amd64.exe, скачиваем и запускаем.

На Ubuntu установка выполняется парой команд:


curl -L https://install.meilisearch.com | sh
sudo mv ./meilisearch /usr/local/bin/

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

Чтобы не запускать движок вручную после перезагрузки, оформим его как сервис. Создаём файл:


sudo nano /etc/systemd/system/meilisearch.service

Помещаем в него следующий текст, подставив свой мастер-ключ:

[Unit]
Description=Meilisearch
After=systemd-user-sessions.service

[Service]
Type=simple
ExecStart=/usr/bin/meilisearch --http-addr 127.0.0.1:7700 --env production --master-key yourMasterKey

[Install]
WantedBy=default.target

Затем включаем и запускаем:


systemctl enable meilisearch
systemctl start meilisearch
systemctl status meilisearch

Установка занимает минимум времени. Актуальные инструкции всегда есть на сайте Meilisearch.

Установка и настройка Scout в Laravel

Для работы с поиском понадобится пакет Laravel Scout. Устанавливаем его через Composer:

composer require laravel/scout

Публикуем конфигурацию:

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

Добавляем SDK для Meilisearch:

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

В файле .env указываем параметры соединения:


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

Добавление поиска в модель

Чтобы модель стала доступной для поиска, её нужно слегка донастроить. Например, для модели Blog это выглядит так:


use Laravel\Scout\Searchable;

class Blog extends Model
{
    use Searchable;

    public function searchableAs()
    {
        return 'blog';
    }

    public function toSearchableArray()
    {
        $this->loadMissing('comments');

        return [
            'id' => $this->id,
            'name' => $this->name,
            'teaser' => $this->teaser,
            'body' => $this->body,
        ];
    }

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

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

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

Ручное создание индекса не требуется. Импорт выполняется одной командой:


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

После этого модели автоматически обновляются в индексе при создании, редактировании или удалении. Сам поиск запускается методом search. Пример вызова в контроллере:


public function search(Request $request)
{
    $text = $request->get('query');
    $blogs = Blog::search($text)->take(20)->get();
    return view('page.search', ['blogs' => $blogs, 'query' => $text]);
}

Фильтры в поиске

Если вы собираетесь использовать where или whereIn, нужный атрибут нужно объявить фильтруемым. Иначе получите ошибку:


Attribute `xxx` is not filterable. Available filterable attributes are: ``.

Удобно задавать эти настройки прямо в конфигурационном файле config/scout.php в секции index-settings. Они автоматически применятся при следующем импорте моделей командой scout:import или отдельной командой scout:sync-index-settings. Пример конфига:


'meilisearch' => [
    'host' => env('MEILISEARCH_HOST', 'http://localhost:7700'),
    'key' => env('MEILISEARCH_KEY'),
    'index-settings' => [
        Blog::class => [
            'filterableAttributes' => ['public'],
            'sortableAttributes' => ['updated_at'],
        ],
    ],
],

Кроме того, Meilisearch и Scout поддерживают настройку ранжирования, информацию об этом можно найти в документации, в разделе rankingRules. Фильтруемые атрибуты достаточно задать один раз, и они будут работать. Пример использования в коде:


$blogs = Blog::search($text)->where('public', 1)->get();

Пагинация

Поиск отлично совместим со стандартной пагинацией Laravel:


$blogs = Blog::search($text)->paginate(20);

В шаблоне останется только вывести ссылки:


{{ $blogs->links() }}

Резюме

Meilisearch хорошо работает с русским языком, учитывает склонения, прощает опечатки. Движок шустрый, хотя при первом запуске индексация может заметно нагрузить систему. Результаты в целом релевантны. Рекомендую Meilisearch как простой и нетребовательный поисковый движок для небольших и средних проектов.

10.01.2022

Обо мне | RSS
© 2010-2026 WDN