Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Як Scout синхронізує модель з пошуковим індексом і як керувати тим, що й коли індексується?

Трейт Searchable підписується на події моделі: після saved модель надсилається в індекс, після deleted - видаляється з нього. Окремо нічого викликати не потрібно.

Що потрапляє в індекс - визначає toSearchableArray:

public function toSearchableArray(): array
{
    return [
        'id' => (int) $this->id,
        'title' => $this->title,
        'body' => strip_tags($this->body),
        'author' => $this->author->name,
        'tags' => $this->tags->pluck('name')->all(),
        'published_at' => $this->published_at?->timestamp,
    ];
}

Правила:

  • лише поля для пошуку й фільтрів, а не вся модель - менший індекс, швидший пошук, менше витоків даних;
  • дати - числом (timestamp), щоб по них можна було фільтрувати й сортувати;
  • дані зі зв'язків - денормалізуються в документ. Але тоді зміна імені автора не оновить його статті в індексі - про це треба подбати окремо.

Що індексувати взагалі:

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

Чернетки не потраплять у пошук, а при знятті з публікації запис видалиться з індексу.

Коли оновлювати:

public function searchIndexShouldBeUpdated(): bool
{
    return $this->wasRecentlyCreated || $this->wasChanged(['title', 'body']);
}

Без цього кожне оновлення лічильника переглядів відправляло б документ в індекс.

Черга - обов'язкова для зовнішніх рушіїв:

// config/scout.php
'queue' => ['connection' => 'redis', 'queue' => 'scout'],

Інакше кожне збереження моделі чекає HTTP-запиту до Meilisearch, а недоступний пошуковий сервер ламає збереження. Завдання Scout унікальні - дублікати для тієї самої моделі не ставляться, поки попереднє в черзі.

Масові операції:

  • Post::where(...)->searchable() / ->unsearchable() - додати чи прибрати набір;
  • Post::withoutSyncingToSearch(fn () => ...) - імпорт чи міграція без тисяч завдань індексування, з одним scout:import потім;
  • масовий update() через query builder не викликає подій моделі - індекс не оновиться, його треба синхронізувати вручну.

Початкове наповнення: php artisan scout:import "App\Models\Post" або scout:queue-import --chunk=500 для великих таблиць, а makeAllSearchableUsing - для жадібного завантаження зв'язків під час імпорту.

Докладніше в документації: Scout: налаштування даних для пошуку

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання