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

Laravel Scout Advanced Meilisearch Laravel Package

alejandroakbal/laravel-scout-advanced-meilisearch

Laravel Scout extension adding advanced query builder filters (comparisons, grouped where/orWhere, between, notIn) plus two compatible drivers: meilisearch_advanced for better Meilisearch filtering/total counts and collection_advanced for in-memory testing.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require alejandroakbal/laravel-scout-advanced-meilisearch
    

    Publish the config file:

    php artisan vendor:publish --provider="Alejandroakbal\ScoutAdvancedMeilisearch\ScoutAdvancedMeilisearchServiceProvider" --tag="config"
    
  2. Configure .env

    SCOUT_DRIVER=meilisearch-advanced
    MEILISEARCH_ADVANCED_HOST=http://localhost:7700
    MEILISEARCH_ADVANCED_API_KEY=your-api-key
    
  3. Set Up Model Add Searchable trait and configure toSearchableArray():

    use Alejandroakbal\ScoutAdvancedMeilisearch\Searchable;
    
    class Product extends Model
    {
        use Searchable;
    
        public function toSearchableArray()
        {
            return [
                'id' => $this->id,
                'title' => $this->title,
                'description' => $this->description,
                'price' => $this->price,
                'tags' => $this->tags->pluck('name'),
            ];
        }
    }
    
  4. First Search

    $results = Product::search('wireless headphones')->get();
    

Implementation Patterns

Core Workflows

  1. Indexing

    • Manual Sync: Force re-indexing via:
      Product::query()->forceSync();
      
    • Batch Sync: Use chunk() for large datasets:
      Product::chunk(100, function ($products) {
          $products->searchable();
      });
      
  2. Advanced Queries

    • Filtering: Use where() with Meilisearch syntax:
      Product::search('headphones')->where('price', '<', 100)->get();
      
    • Typo Tolerance: Enable via config:
      'typo_tolerance' => 'strict',
      
    • Faceting: Retrieve aggregated filters:
      $results = Product::search('headphones')->get(['facets' => ['tags']]);
      
  3. Pagination

    • Use Laravel’s built-in pagination:
      $results = Product::search('headphones')->paginate(10);
      
  4. Custom Sorting

    • Override toSearchableArray() to include sort fields:
      public function toSearchableArray()
      {
          return [
              'title' => $this->title,
              '_sortable_price' => $this->price, // Custom field for sorting
          ];
      }
      
    • Query with:
      Product::search('headphones')->sortBy('_sortable_price', 'desc')->get();
      
  5. Hybrid Search Combine with other Scout drivers (e.g., database fallback):

    Product::search('headphones')->with(['fallback' => true])->get();
    

Integration Tips

  • Event Listeners: Hook into searchableSynced/searchableDeleted for analytics or logging.
  • Middleware: Restrict search access:
    Route::middleware(['auth'])->group(function () {
        Route::get('/search', [SearchController::class, 'index']);
    });
    
  • API Responses: Normalize Meilisearch results:
    return Product::search(request('q'))->get()->map(function ($product) {
        return $product->load('reviews')->toArray();
    });
    

Gotchas and Tips

Pitfalls

  1. Schema Mismatches

    • Ensure toSearchableArray() returns a consistent structure. Meilisearch throws errors on schema changes.
    • Fix: Use meilisearch:reset-index artisan command to rebuild the index:
      php artisan meilisearch:reset-index --model=Product
      
  2. Rate Limiting

    • Meilisearch has default rate limits (30 queries/sec). Exceeding this may return 429 errors.
    • Fix: Implement exponential backoff in queries or upgrade your Meilisearch plan.
  3. Case Sensitivity

    • Meilisearch is case-sensitive by default. Use unicode tokenizer for case-insensitive searches:
      'searchableAs' => 'unicode',
      
  4. Nested Relationships

    • Avoid deep nesting in toSearchableArray(); flatten relationships to prevent performance issues.
    • Tip: Use with() to eager-load relationships after searching:
      $products = Product::search('headphones')->with('reviews')->get();
      
  5. Partial Updates

    • Meilisearch doesn’t support partial updates natively. Delete and re-index the model instead:
      $product->deleteFromSearch();
      $product->searchable();
      

Debugging

  • Log Queries: Enable Scout logging in config/scout.php:
    'log' => env('SCOUT_LOG', true),
    
  • Meilisearch Dashboard: Monitor index health at http://localhost:7700.
  • Raw Queries: Inspect the raw Meilisearch query via:
    $query = Product::search('headphones')->toMeilisearchQuery();
    

Extension Points

  1. Custom Analyzers Override the default analyzer in config/scout-advanced-meilisearch.php:

    'analyzer' => 'fr', // French analyzer
    
  2. Webhooks Subscribe to Meilisearch events (e.g., index updates) via the Meilisearch HTTP API.

  3. Multi-Tenancy Use separate Meilisearch indices per tenant:

    public function getSearchableIndex()
    {
        return 'tenant_' . auth()->id() . '_products';
    }
    
  4. Async Indexing Queue searchable() calls for background processing:

    ProductCreated::dispatch($product); // Event dispatches SearchableJob
    

    Register the job:

    use Alejandroakbal\ScoutAdvancedMeilisearch\Jobs\SearchableJob;
    
    SearchableJob::dispatch($product);
    
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope