laravel-scout

Auto-invoked skill

Full-text search with Algolia, Meilisearch, or Typesense

Trigger Keywords

This skill automatically activates when Claude detects these keywords:

scout search algolia meilisearch typesense full-text search

Overview

The laravel-scout skill provides expertise for implementing full-text search in Laravel using Scout with various drivers including Algolia, Meilisearch, Typesense, and the database driver.

What This Skill Provides

  • Search Setup - Install and configure Scout with your preferred driver
  • Model Configuration - Make models searchable with custom indexes
  • Advanced Search - Filters, facets, and custom ranking
  • Bulk Operations - Import and flush indexes
  • Queue Integration - Background indexing

Quick Start

# Install Scout
composer require laravel/scout

# Install Meilisearch driver
composer require meilisearch/meilisearch-php

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

# Start Meilisearch (Docker)
docker run -d -p 7700:7700 getmeili/meilisearch:latest

Model Setup

<?php

namespace App\Models;

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

final class Product extends Model
{
    use Searchable;

    public function toSearchableArray(): array
    {
        return [
            'id' => $this->id,
            'name' => $this->name,
            'description' => $this->description,
            'category' => $this->category->name,
            'price' => $this->price,
            'in_stock' => $this->in_stock,
        ];
    }

    public function searchableAs(): string
    {
        return 'products_index';
    }

    // Only index published products
    public function shouldBeSearchable(): bool
    {
        return $this->is_published;
    }
}

Searching

// Basic search
$products = Product::search('laptop')->get();

// With pagination
$products = Product::search('laptop')->paginate(15);

// With filters (Meilisearch)
$products = Product::search('laptop')
    ->where('in_stock', true)
    ->where('price', '<=', 1000)
    ->get();

// With custom options
$products = Product::search('laptop', function ($meilisearch, $query, $options) {
    $options['filter'] = ['category = "electronics"'];
    $options['sort'] = ['price:asc'];
    return $meilisearch->search($query, $options);
})->get();

Configuration

// config/scout.php
return [
    'driver' => env('SCOUT_DRIVER', 'meilisearch'),

    'meilisearch' => [
        'host' => env('MEILISEARCH_HOST', 'http://127.0.0.1:7700'),
        'key' => env('MEILISEARCH_KEY'),
        'index-settings' => [
            Product::class => [
                'filterableAttributes' => ['category', 'in_stock', 'price'],
                'sortableAttributes' => ['price', 'created_at'],
                'searchableAttributes' => ['name', 'description'],
            ],
        ],
    ],

    'queue' => true, // Queue indexing operations
];

Indexing Operations

# Import all records
php artisan scout:import "App\Models\Product"

# Flush all records
php artisan scout:flush "App\Models\Product"

# Sync index settings
php artisan scout:sync-index-settings

Common Pitfalls

  • Not queuing indexing - Set queue => true for better performance
  • Missing filterable attributes - Configure before using where()
  • Indexing large datasets - Use scout:import with chunking
  • Not handling search errors - Wrap in try-catch for external services
  • Indexing sensitive data - Only include searchable fields

Best Practices

  • Queue indexing operations in production
  • Only index fields needed for search
  • Use shouldBeSearchable() to filter indexed records
  • Configure sortable/filterable attributes upfront
  • Monitor index size and search performance
  • Use separate indexes per environment

Related Skills