Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Scout Laravel Package

laravel/scout

Laravel Scout adds driver-based full-text search to Eloquent models, automatically syncing model changes to your search indexes. Supports Algolia, Meilisearch, and Typesense for fast, scalable searching in Laravel apps.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require laravel/scout
    

    For a specific driver (e.g., Algolia, Meilisearch, or Typesense), install its corresponding package:

    composer require algolia/algoliasearch-client-php  # Algolia
    composer require meilisearch/meilisearch-php        # Meilisearch
    composer require typesense/typesense-php           # Typesense
    
  2. Configure Driver: Add your driver configuration to .env (e.g., SCOUT_DRIVER=algolia, ALGOLIA_APP_ID=..., ALGOLIA_SECRET=...). Default driver is now collection (in-memory), but switch to your preferred driver.

  3. Make a Model Searchable: Use the HasScoutSearchable trait in your Eloquent model:

    use Laravel\Scout\Searchable;
    
    class Post extends Model
    {
        use Searchable;
    
        // Model logic...
    }
    
  4. First Search:

    $results = Post::search('laravel')->get();
    

    Scout automatically syncs model changes to the search index.


First Use Case: Basic Search

// Search posts with a query
$posts = Post::search('backend development')->get();

// Get first result
$firstPost = Post::search('backend')->first();

// Paginate results
$posts = Post::search('laravel')->paginate(10);

Implementation Patterns

Core Workflows

  1. Syncing Data: Scout automatically syncs model changes (create/update/delete) to the search index. For bulk operations, use:

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

    Or queue the import for large datasets:

    php artisan scout:queue "App\Models\Post"
    
  2. Customizing Searchable Attributes: Override toSearchableArray() to define which fields are searchable:

    public function toSearchableArray()
    {
        return [
            'title' => $this->title,
            'body' => $this->body,
            'tags' => $this->tags,
        ];
    }
    
  3. Filtering Results: Use the where() method to filter search results:

    $posts = Post::search('laravel')
        ->where('category', 'backend')
        ->where('published', true)
        ->get();
    
  4. Advanced Queries: Use query callbacks for complex logic:

    $posts = Post::search(function ($query) {
        $query->where('title', 'laravel')
              ->where('category', 'backend')
              ->orderByDesc('created_at');
    })->get();
    
  5. Customizing Engines: Extend the default engine behavior by creating a custom engine:

    use Laravel\Scout\Engines\Engine;
    
    class CustomEngine extends Engine
    {
        public function update($model)
        {
            // Custom logic
        }
    
        public function delete($model)
        {
            // Custom logic
        }
    
        public function search($query)
        {
            // Custom logic
        }
    }
    

    Register it in config/scout.php:

    'engine' => CustomEngine::class,
    

Integration Tips

  1. Queueing Search Jobs: For performance, queue searchable sync jobs:

    Post::addGlobalScope(new SearchableByUserScope());
    

    Configure queue settings in .env:

    SCOUT_QUEUE_CHUNK=100
    SCOUT_QUEUE_WORKER=redis
    
  2. Soft Deletes: Scout handles soft deletes automatically. Use forceDelete() to permanently remove from the index:

    $post->forceDelete(); // Removes from search index
    
  3. Driver-Specific Features:

    • Algolia: Use setSettings() to customize index behavior.
    • Meilisearch: Leverage embedder settings for nested data.
    • Typesense: Configure custom indexes or disable prefixes.
  4. Testing: Use the collection driver for testing:

    config(['scout.driver' => 'collection']);
    

    Mock search responses in tests:

    $this->partialMock(Engine::class, function ($mock) {
        $mock->shouldReceive('search')->andReturn([...]);
    });
    

Gotchas and Tips

Pitfalls

  1. Race Conditions: Avoid concurrent writes to the same model during imports. Use scout:queue for large datasets:

    php artisan scout:queue "App\Models\Post"
    
  2. Driver-Specific Quirks:

    • Algolia: Ensure ALGOLIA_APP_ID and ALGOLIA_SECRET are correctly set. Numeric filters may require explicit casting.
    • Meilisearch: Escape filter strings with double quotes to avoid syntax errors.
    • Typesense: Handle missing collections gracefully during searches.
  3. Pagination Issues: Typesense may return limited records due to integer overflow. Use perPage() explicitly:

    $posts = Post::search('query')->paginate(20)->perPage(20);
    
  4. Soft Deletes: Scout skips deleted models by default. Use forceDelete() to ensure removal from the index:

    $post->delete(); // Soft delete (keeps in index)
    $post->forceDelete(); // Hard delete (removes from index)
    
  5. Unique Indexing: Prevent duplicate jobs during reindexing by enabling unique indexing:

    php artisan scout:import "App\Models\Post" --unique
    

Debugging Tips

  1. Log Search Queries: Enable Scout logging in config/scout.php:

    'log' => env('SCOUT_LOG', false),
    
  2. Check Index Settings: Sync index settings manually:

    php artisan scout:settings "App\Models\Post"
    
  3. Verify Driver Connection: Test your driver connection:

    php artisan scout:flush "App\Models\Post"
    php artisan scout:import "App\Models\Post"
    
  4. Handle Missing Collections: For Typesense, ensure collections exist before searching:

    if (!$this->collectionExists($model)) {
        $this->createCollection($model);
    }
    

Extension Points

  1. Custom Searchable Attributes: Dynamically compute searchable attributes:

    public function toSearchableArray()
    {
        return [
            'content' => $this->title . ' ' . $this->body,
            'slug' => Str::slug($this->title),
        ];
    }
    
  2. Post-Search Callbacks: Modify results after search:

    Post::search('query')->afterRawSearch(function ($results) {
        return $results->map(fn ($item) => [
            'id' => $item['id'],
            'title' => $item['title'],
            'score' => $item['_score'],
        ]);
    })->get();
    
  3. Custom Engines: Extend Laravel\Scout\Engines\Engine for full control over search behavior. Example:

    class CustomEngine extends Engine
    {
        public function search($query)
        {
            $results = $this->client->search($query->toArray());
            return $results['hits'];
        }
    }
    
  4. Driver-Specific Optimizations:

    • Algolia: Use setSettings() to optimize for your use case.
    • Meilisearch: Configure embedder settings for nested data.
    • Typesense: Tune pagination and sorting for performance.

Config Quirks

  1. Default Driver: The default driver is now collection (in-memory). Change it in .env:

    SCOUT_DRIVER=algolia
    
  2. Queue Configuration: Configure queue settings in .env:

    SCOUT_QUEUE_CHUNK=100
    SCOUT_QUEUE_WORKER=redis
    
  3. Environment-Specific Drivers: Use different drivers per environment:

    config(['scout.driver' => env('SCOUT_DRIVER', 'collection')]);
    
  4. Driver-Specific Keys: Ensure all required keys are set in .env (e.g., ALGOLIA_APP_ID, MEILI_MASTER_KEY).


Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony