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 Extended Laravel Package

algolia/scout-extended

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require algolia/scout-extended
    

    Ensure algolia/algoliasearch-client-php is also installed (dependency).

  2. Configuration: Publish the config file:

    php artisan vendor:publish --provider="Algolia\ScoutExtended\ScoutExtendedServiceProvider" --tag="scout-extended-config"
    

    Update .env with your Algolia credentials:

    ALGOLIA_APP_ID=your_app_id
    ALGOLIA_SECRET=your_secret_key
    ALGOLIA_SEARCH=your_search_engine_name
    
  3. First Use Case: Add Scoutable and Searchable traits to your model:

    use Algolia\ScoutExtended\Searchable;
    
    class Product extends Model
    {
        use Scoutable, Searchable;
    }
    

    Define a toSearchableArray() method to specify searchable fields:

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

    Run the indexer:

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

Where to Look First

  • Official Documentation: Start here for setup, configuration, and advanced features.
  • config/scout-extended.php: Review settings like index_name, settings, and mappings for customization.
  • Model Traits: Focus on Searchable for field transformations and Scoutable for indexing logic.
  • Artisan Commands: scout:import, scout:flush, and scout:forget are critical for daily workflows.

Implementation Patterns

Core Workflows

1. Indexing Models

  • Bulk Import: Use scout:import for initial setup or after data migrations:
    php artisan scout:import "App\Models\User App\Models\Product"
    
  • Incremental Updates: Leverage save() or update() triggers via Scoutable trait:
    $product->save(); // Automatically updates Algolia index
    
  • Manual Indexing: Force re-index a single model:
    $product->searchable(); // Rebuilds searchable array
    $product->save();
    

2. Searching Data

  • Basic Search: Use the search() method with query builder syntax:
    $results = Product::search('laptop')->get();
    
  • Advanced Queries: Chain methods for filtering, pagination, and faceting:
    $results = Product::search('laptop')
        ->where('price', '<', 1000)
        ->where('category', 'electronics')
        ->with('reviews')
        ->get();
    
  • Typo Tolerance: Enable typo tolerance in queries:
    $results = Product::search('laptpo')->typoTolerance()->get();
    

3. Real-Time Updates

  • Event-Based Indexing: Use searchable() in model events (e.g., created, updated):
    class Product extends Model
    {
        protected static function booted()
        {
            static::updated(function ($product) {
                $product->searchable();
            });
        }
    }
    
  • Batch Processing: For large datasets, use chunking:
    Product::chunk(100, function ($products) {
        foreach ($products as $product) {
            $product->searchable();
            $product->save();
        }
    });
    

4. Customizing Search Behavior

  • Field Mappings: Override toSearchableArray() for dynamic fields:
    public function toSearchableArray()
    {
        return [
            'name' => $this->name,
            'formatted_price' => '$' . number_format($this->price, 2),
        ];
    }
    
  • Searchable Attributes: Define which fields are searchable in config/scout-extended.php:
    'mappings' => [
        'Product' => [
            'name' => 'text',
            'price' => 'number',
        ],
    ],
    
  • Custom Analyzers: Configure analyzers for specific fields:
    'settings' => [
        'attributesForFaceting' => ['category', 'brand'],
        'customRanking' => ['desc(price)'],
    ],
    

5. Integration with Laravel Features

  • API Resources: Serialize search results for APIs:
    return ProductResource::collection($results);
    
  • Scout Extended Facets: Use faceted search for filtering:
    $facets = Product::search('laptop')->facets(['category', 'brand'])->getFacets();
    
  • Pagination: Paginate results directly:
    $results = Product::search('laptop')->paginate(10);
    

Pro Tips

  • Use scout:flush before major deployments to avoid stale data.
  • Leverage scout:forget to remove specific models from the index:
    php artisan scout:forget App\Models\Product 123
    
  • Monitor Indexing with Algolia’s dashboard or custom logs:
    ScoutExtended::logQuery(); // Enable logging in config
    

Gotchas and Tips

Pitfalls

  1. Index Name Conflicts:

    • Issue: Multiple environments (e.g., dev, prod) using the same index name.
    • Fix: Override getScoutKeyName() in your model or configure index_name in .env:
      ALGOLIA_INDEX_NAME=products_prod
      
    • Config Override:
      class Product extends Model
      {
          public function getScoutKeyName()
          {
              return config('scout-extended.index_name') . '_' . config('app.env');
          }
      }
      
  2. Rate Limits:

    • Issue: Hitting Algolia’s rate limits during bulk imports.
    • Fix:
      • Use scout:import with --chunk flag:
        php artisan scout:import "App\Models\Product" --chunk=100
        
      • Implement exponential backoff in custom scripts.
  3. Stale Data:

    • Issue: Models not updating in Algolia due to failed save() calls.
    • Fix:
      • Add error handling in model events:
        static::updated(function ($product) {
            try {
                $product->searchable();
                $product->save();
            } catch (\Exception $e) {
                \Log::error("Algolia update failed for product {$product->id}: " . $e->getMessage());
            }
        });
        
      • Use scout:flush and re-import if needed.
  4. Field Type Mismatches:

    • Issue: Algolia rejects data due to incorrect field types (e.g., sending a string to a number field).
    • Fix:
      • Validate toSearchableArray() output:
        public function toSearchableArray()
        {
            return [
                'price' => (float) $this->price, // Ensure numeric fields are cast
            ];
        }
        
      • Use config/scout-extended.php to enforce types:
        'mappings' => [
            'Product' => [
                'price' => 'number',
            ],
        ],
        
  5. Circular References:

    • Issue: Eager-loading relationships causes infinite loops in toSearchableArray().
    • Fix:
      • Explicitly define relationships:
        public function toSearchableArray()
        {
            return [
                'name' => $this->name,
                'category' => $this->category->name, // Direct access
            ];
        }
        
      • Use with() selectively:
        $results = Product::search('laptop')->with(['category'])->get();
        

Debugging

  1. Enable Logging:

    • Add to config/scout-extended.php:
      'log' => [
          'enabled' => true,
          'path' => storage_path('logs/scout-extended.log'),
      ],
      
    • Check logs for failed queries or indexing issues.
  2. Algolia Debugger:

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.
besmartand-pro/php-quality-config
sentix/ai-chatbot
terminal42/code-quality-tools
codifyo/ts-generator-bundle
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity