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

adimeo-data-suite/search-client

Laravel/PHP search client for Adimeo Data Suite. Provides a simple API to connect to the service, send search queries, handle responses, and integrate search features into your application with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require adimeo-data-suite/search-client
    

    Requires PHP 8.1+ and Laravel 9+.

  2. Configuration Publish the config file:

    php artisan vendor:publish --provider="Adimeo\SearchClient\SearchClientServiceProvider"
    

    Update .env with your search engine credentials (e.g., Algolia, Meilisearch, or Elasticsearch).

  3. First Use Case: Basic Search

    use Adimeo\SearchClient\SearchClient;
    
    $client = app(SearchClient::class);
    $results = $client->search('products', 'laptop');
    return response()->json($results);
    
    • Replace 'products' with your index name.
    • The method returns a SearchResult object with hits, total pages, and metadata.
  4. Key Files to Review

    • config/search-client.php: Engine-specific settings (host, API key, etc.).
    • src/SearchClient.php: Core client class and available methods.
    • src/Contracts/SearchEngine.php: Interface for engine-specific implementations.

Implementation Patterns

Workflows

1. Index Management

  • Create/Update Index:
    $client->createIndex('products', [
        'settings' => ['searchableAttributes' => ['name', 'description']],
    ]);
    
  • Delete Index:
    $client->deleteIndex('products');
    
  • Bulk Indexing: Use the addDocuments method for batch inserts:
    $client->addDocuments('products', [
        ['name' => 'Laptop', 'price' => 999],
        ['name' => 'Phone', 'price' => 699],
    ]);
    

2. Querying

  • Basic Search with Filters:
    $results = $client->search('products', 'laptop', [
        'filters' => 'price > 500',
        'attributesToRetrieve' => ['name', 'price'],
    ]);
    
  • Pagination:
    $results = $client->search('products', '', [
        'page' => 2,
        'hitsPerPage' => 10,
    ]);
    
  • Typo Tolerance:
    $results = $client->search('products', 'laptp', [
        'typoTolerance' => 'min',
    ]);
    

3. Integration with Laravel

  • Service Provider Binding: Bind the client to the container in AppServiceProvider:
    $this->app->singleton(SearchClient::class, function ($app) {
        return new SearchClient(config('search-client.engine'));
    });
    
  • API Resources: Transform search results into API resources:
    return ProductResource::collection($results->getHits());
    
  • Caching: Cache frequent queries using Laravel’s cache:
    $cacheKey = "search:products:{$query}";
    return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($client, $query) {
        return $client->search('products', $query);
    });
    

4. Event-Driven Updates

  • Listen for model events (e.g., saved) and sync with the search index:
    use Adimeo\SearchClient\Events\DocumentSynced;
    
    Product::saved(function ($product) {
        event(new DocumentSynced('products', $product->toArray()));
    });
    
  • Dispatch events manually:
    event(new DocumentSynced('products', $productData));
    

Integration Tips

  1. Multi-Engine Support The package supports multiple search engines via the SearchEngine contract. Implement custom engines by extending BaseSearchEngine.

  2. Laravel Scout Alternative Use the client as a drop-in replacement for Scout:

    // In your model's toSearchableArray()
    return $this->searchClient->prepareForSearch($this->attributesToArray());
    
  3. Testing Mock the SearchClient in tests:

    $mock = Mockery::mock(SearchClient::class);
    $mock->shouldReceive('search')->andReturn(new SearchResult([], 0, 0));
    $this->app->instance(SearchClient::class, $mock);
    
  4. Async Processing Use Laravel Queues to offload index updates:

    SyncDocuments::dispatch('products', $documents)->onQueue('search');
    

Gotchas and Tips

Pitfalls

  1. Engine-Specific Quirks

    • Algolia: Uses attributesForFaceting instead of facets.
    • Meilisearch: Requires primaryKey in index settings.
    • Elasticsearch: May need custom analyzers for text fields.
    • Fix: Check the config/search-client.php for engine-specific defaults and override as needed.
  2. Rate Limiting Some engines (e.g., Algolia) enforce rate limits. Handle SearchClientException:

    try {
        $results = $client->search('products', $query);
    } catch (SearchClientException $e) {
        if ($e->getCode() === 429) {
            // Retry or notify admin
        }
    }
    
  3. Data Serialization Ensure your model data is serializable (no closures, resources, or circular references). Use json_encode($data) to test.

  4. Index Naming Collisions Avoid reserved names (e.g., _users). Prefix indices with your app name (e.g., app_products).

Debugging

  1. Enable Logging Add to config/search-client.php:

    'debug' => env('SEARCH_DEBUG', false),
    

    Logs will appear in storage/logs/laravel.log.

  2. Raw API Calls Access the underlying engine client for debugging:

    $rawResponse = $client->getEngine()->raw('search', ['index' => 'products', 'q' => 'laptop']);
    
  3. Common Errors

    • 404 Not Found: Index doesn’t exist. Run createIndex first.
    • 403 Forbidden: Invalid API key. Check .env.
    • Validation Errors: Malformed query or filters. Validate with the engine’s API docs.

Tips

  1. Partial Updates Use updateDocuments to modify existing records:

    $client->updateDocuments('products', [
        ['id' => 1, 'name' => 'Updated Laptop'],
    ]);
    
  2. Synonyms and Stop Words Configure in index settings:

    $client->createIndex('products', [
        'settings' => [
            'synonyms' => ['laptop' => ['notebook']],
            'stopWords' => ['the', 'and'],
        ],
    ]);
    
  3. Performance

    • Batch Size: Limit addDocuments to 1000 records per batch.
    • Async Indexing: Use queues for large datasets.
    • Caching: Cache index settings and frequent queries.
  4. Extension Points

    • Custom Engines: Extend BaseSearchEngine and register via the service provider.
    • Query Builders: Override buildQuery in SearchClient for custom logic.
    • Transformers: Use Adimeo\SearchClient\Contracts\Transformer to map results to Eloquent models.
  5. Environment-Specific Config Use Laravel’s config caching to switch engines per environment:

    // config/search-client.php
    'engine' => env('SEARCH_ENGINE', 'algolia'),
    

    Set SEARCH_ENGINE=meilisearch in .env.testing.

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