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

Search Laravel Package

baks-dev/search

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require baks-dev/search
   php artisan vendor:publish --provider="BaksDev\Search\SearchServiceProvider" --tag="search-config"
  • Publishes default config (config/search.php) and migrations (if any).
  1. Basic Configuration:

    • Edit config/search.php to define:
      'engines' => [
          'default' => [
              'driver' => 'meilisearch', // or 'elasticsearch', 'algolia', etc.
              'config' => [
                  'host' => env('SEARCH_HOST'),
                  'api_key' => env('SEARCH_API_KEY'),
              ],
          ],
      ],
      
    • Add environment variables to .env:
      SEARCH_HOST=localhost:7700
      SEARCH_API_KEY=your_api_key
      
  2. First Search Query:

    use BaksDev\Search\Facades\Search;
    
    $results = Search::query('laravel')->engine('default')->search();
    
    • Returns a collection of results with metadata (e.g., score, id).
  3. Indexing a Model:

    use BaksDev\Search\Traits\Searchable;
    
    class Post extends Model
    {
        use Searchable;
    
        protected $searchable = [
            'columns' => ['title', 'body'],
            'engine' => 'default',
        ];
    }
    
    • Run php artisan search:index to index all Post models.

Where to Look First

  • Config File: config/search.php for engine settings.
  • Facade: BaksDev\Search\Facades\Search for direct queries.
  • Traits: Searchable for Eloquent model integration.
  • Commands: php artisan search:* for CLI tools (e.g., indexing, reindexing).
  • Events: Searching, SearchResult for custom logic.

First Use Case: Full-Text Search

// Search posts by title/body
$posts = Search::query('laravel framework')
    ->engine('default')
    ->filter('category', 'tutorial')
    ->paginate(10)
    ->get();
  • Output: Paginated results with score and id for sorting/filtering.

Implementation Patterns

1. Model Integration

  • Trait-Based:

    class Product extends Model
    {
        use Searchable;
    
        protected $searchable = [
            'columns' => ['name', 'description', 'sku'],
            'engine' => 'algolia',
            'settings' => [
                'searchableAttributes' => ['name', 'description'],
            ],
        ];
    }
    
    • Automatically syncs changes to the search engine via model events (saved, deleted).
  • Manual Indexing:

    // Index a single model
    $post = Post::find(1);
    $post->searchableIndex();
    
    // Reindex all models
    php artisan search:reindex Post
    

2. Query Building

  • Fluent Interface:

    $results = Search::query('php')
        ->engine('elasticsearch')
        ->filter('published', true)
        ->sortBy('created_at', 'desc')
        ->limit(20)
        ->search();
    
    • Supports chaining for readability.
  • Dynamic Filters:

    $filters = request()->input('filters', []);
    $results = Search::query($q)
        ->addFilters($filters)
        ->search();
    

3. Engine-Specific Features

  • Meilisearch:
    Search::engine('meilisearch')->typoTolerance()->search();
    
  • Elasticsearch:
    Search::engine('elasticsearch')->highlight('body')->search();
    

4. Pagination and Cursors

// Pagination
$results = Search::query($q)->paginate(15);

// Cursor-based (for large datasets)
$results = Search::query($q)->cursor()->limit(50)->search();

5. Custom Engines

Extend the package by creating a custom driver:

namespace App\Search\Engines;

use BaksDev\Search\Contracts\Engine;

class CustomEngine implements Engine
{
    public function search(string $query, array $options): array
    {
        // Custom logic
    }
}

Register in config/search.php:

'engines' => [
    'custom' => [
        'driver' => \App\Search\Engines\CustomEngine::class,
    ],
],

6. Event Listeners

Listen for search events to modify results or log queries:

// app/Providers/EventServiceProvider.php
protected $listen = [
    \BaksDev\Search\Events\Searching::class => [
        \App\Listeners\LogSearchQuery::class,
    ],
];

Gotchas and Tips

Pitfalls

  1. Engine-Specific Quirks:

    • Meilisearch: Requires primaryKey in $searchable if not id.
      protected $searchable = [
          'columns' => ['title'],
          'primaryKey' => 'slug',
      ];
      
    • Elasticsearch: May need analyzer settings for non-English text.
      'settings' => [
          'analysis' => [
              'analyzer' => ['custom_analyzer' => [...]],
          ],
      ],
      
  2. Rate Limiting:

    • Some engines (e.g., Algolia) throttle requests. Use ->throttle(100) to batch queries:
      Search::query($q)->throttle(100)->search();
      
  3. Index Sync Delays:

    • Model changes may not immediately reflect in search results. Use ->sync() to force sync:
      $post->searchableSync();
      
  4. Case Sensitivity:

    • Default behavior varies by engine. Explicitly set case sensitivity:
      Search::query($q)->caseSensitive()->search(); // Meilisearch/Elasticsearch
      
  5. Memory Limits:

    • Large reindexing jobs may hit PHP memory limits. Use chunking:
      php artisan search:reindex Post --chunk=100
      

Debugging Tips

  1. Enable Logging:

    Search::enableLogging();
    
    • Logs queries to storage/logs/search.log.
  2. Raw Engine Queries:

    • Access the underlying engine query for debugging:
      $rawQuery = Search::query($q)->getRawQuery();
      
  3. Test Locally:

    • Use Docker for engines like Meilisearch/Elasticsearch:
      # docker-compose.yml
      services:
        meilisearch:
          image: getmeili/meilisearch:v1.4
          ports:
            - "7700:7700"
      
  4. Common Errors:

    • "Engine Not Found": Verify config/search.php and environment variables.
    • "Index Not Found": Run php artisan search:reindex Model to ensure indices exist.
    • Timeouts: Increase search.timeout in config (default: 5 seconds).

Performance Tips

  1. Selective Indexing:

    • Only index necessary columns to reduce payload size:
      protected $searchable = [
          'columns' => ['title', 'tags'], // Exclude heavy fields like 'body'
      ];
      
  2. Caching Results:

    • Cache frequent queries:
      $results = Cache::remember("search_{$q}", now()->addHours(1), function() use ($q) {
          return Search::query($q)->search();
      });
      
  3. Async Indexing:

    • Use queues for bulk indexing:
      Post::chunk(200, function ($posts) {
          Search::queueIndex($posts);
      });
      
  4. Engine Optimization:

    • Meilisearch: Use searchableAttributes and displayedAttributes to optimize.
    • Elasticsearch: Configure index.mapping for better performance.

Extension Points

  1. Custom Scoring:

    • Override scoring logic by extending the SearchBuilder:
      namespace App\Search;
      
      use BaksDev\Search\SearchBuilder;
      
      class CustomSearchBuilder extends SearchBuilder
      {
          protected function applyCustomScoring(array $results): array
          {
              // Modify scores based on business logic
              return $results;
          }
      }
      
    • Bind in AppServiceProvider:
      Search::extend('custom', function () {
          return new CustomSearchBuilder();
      });
      
  2. Pre/Post-Processors:

    • Add logic before/after search execution:
      Search::preProcess(function ($query) {
          // Modify query object
      });
      
      Search::postProcess
      
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.
aimeos/prisma
besmartand-pro/php-quality-config
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
christhompsontldr/laravel-inky
spatie/mailcoach-vapor
spatie/laravel-javascript-views