Как правильно реализовать поиск в Laravel

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

Разберёмся, как правильно проектировать поиск в Laravel: от базового решения до production-уровня.

Почему обычный LIKE-поиск это не лучшее решение

Самая распространённая реализация выглядит примерно так:

Post::where('title', 'like', "%{$query}%")->get();

Такой подход работает, но у него есть серьёзные ограничения:

  • плохо масштабируется на больших таблицах;

  • не учитывает релевантность результатов;

  • не умеет работать с опечатками;

  • не поддерживает сложные фильтры;

  • медленно работает при большом объёме данных.

Когда база данных начинает расти, подобные запросы становятся узким местом всей системы.

Базовый поиск через Eloquent

Для небольших проектов можно использовать стандартные возможности Eloquent.

Контроллер

public function search(Request $request)
{
    $query = $request->input('q');

    $posts = Post::query()
        ->where('title', 'like', "%{$query}%")
        ->orWhere('content', 'like', "%{$query}%")
        ->paginate(10);

    return view('posts.index', compact('posts'));
}

Форма поиска

<form method="GET" action="/search">
    <input type="text" name="q" placeholder="Search..." value="{{ request('q') }}">
</form>

Основные рекомендации

  1. Используйте paginate() вместо get().

  2. Ограничивайте количество полей.

  3. Добавляйте индексы на поисковые колонки.

Это простой и понятный подход, но он подходит только для небольших наборов данных.

Улучшение архитектуры с помощью Query Scopes

Когда поиск становится сложнее, стоит вынести логику в Eloquent scopes. Это делает код чище и повторно используемым.

Пример scope

public function scopeSearch($query, $term)
{
    return $query->where('title', 'like', "%{$term}%")
        ->orWhere('content', 'like', "%{$term}%");
}

Использование

Post::search($request->q)->paginate(10);

Преимущества:

  • чистый контроллер;

  • переиспользование логики;

  • удобная композиция фильтров.

Использование Full-Text Search в базе данных

Если проект работает на MySQL или PostgreSQL, можно использовать встроенный full-text search.

Пример MySQL

Post::whereFullText('content', $query)->get();

Full-text поиск работает быстрее и лучше ранжирует результаты по релевантности.

В Laravel такие запросы можно комбинировать с обычными фильтрами и дополнительной обработкой результатов.

Production-подход: Laravel Scout

Когда данных становится много (десятки тысяч или миллионы записей), правильным решением становится использование специализированных поисковых движков.

Laravel предоставляет для этого пакет Laravel Scout который позволяет интегрировать:

  • Meilisearch

  • Algolia

  • Elasticsearch

Scout синхронизирует модели Laravel с поисковым индексом и выполняет быстрый поиск по нему.

Пример реализации Scout

Установка

composer require laravel/scout

Подключение к модели

use Laravel\Scout\Searchable;

class Post extends Model
{
    use Searchable;
}

Поиск

$posts = Post::search($query)->get();

Scout автоматически индексирует модели и делает поиск значительно быстрее.

Использование Meilisearch

Одним из популярных движков для Laravel является Meilisearch. Он обеспечивает:

  • полнотекстовый поиск;

  • tolerance к опечаткам;

  • поиск по синонимам;

  • фильтрацию и сортировку;

  • автодополнение.

Кроме того, он очень прост в установке и отлично подходит для SaaS-приложений.

Полезные практики

1. Индексируйте только нужные поля

public function toSearchableArray()
{
    return [
        'title' => $this->title,
        'content' => $this->content,
    ];
}

2. Используйте пагинацию

Никогда не возвращайте большие коллекции без paginate().

3. Ограничивайте результаты

Post::search($query)->take(20)->get();

4. Добавляйте фильтры

Post::search($query)
    ->where('status', 'published')
    ->get();

Как итог

Правильная реализация поиска в Laravel зависит от масштаба проекта.

Для небольших приложений достаточно:

  • LIKE запросов

  • Eloquent scopes

Для средних проектов:

  • Full-text search в базе данных

Для крупных систем:

  • Laravel Scout

  • Meilisearch или Elasticsearch

Такой подход позволяет постепенно масштабировать поиск без переписывания всей системы.

Комментарии (0)

Войдите, чтобы оставить комментарий

Похожие статьи