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.
Installation
composer require adimeo-data-suite/search-client
Requires PHP 8.1+ and Laravel 9+.
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).
First Use Case: Basic Search
use Adimeo\SearchClient\SearchClient;
$client = app(SearchClient::class);
$results = $client->search('products', 'laptop');
return response()->json($results);
'products' with your index name.SearchResult object with hits, total pages, and metadata.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.$client->createIndex('products', [
'settings' => ['searchableAttributes' => ['name', 'description']],
]);
$client->deleteIndex('products');
addDocuments method for batch inserts:
$client->addDocuments('products', [
['name' => 'Laptop', 'price' => 999],
['name' => 'Phone', 'price' => 699],
]);
$results = $client->search('products', 'laptop', [
'filters' => 'price > 500',
'attributesToRetrieve' => ['name', 'price'],
]);
$results = $client->search('products', '', [
'page' => 2,
'hitsPerPage' => 10,
]);
$results = $client->search('products', 'laptp', [
'typoTolerance' => 'min',
]);
AppServiceProvider:
$this->app->singleton(SearchClient::class, function ($app) {
return new SearchClient(config('search-client.engine'));
});
return ProductResource::collection($results->getHits());
$cacheKey = "search:products:{$query}";
return Cache::remember($cacheKey, now()->addMinutes(5), function () use ($client, $query) {
return $client->search('products', $query);
});
saved) and sync with the search index:
use Adimeo\SearchClient\Events\DocumentSynced;
Product::saved(function ($product) {
event(new DocumentSynced('products', $product->toArray()));
});
event(new DocumentSynced('products', $productData));
Multi-Engine Support
The package supports multiple search engines via the SearchEngine contract. Implement custom engines by extending BaseSearchEngine.
Laravel Scout Alternative Use the client as a drop-in replacement for Scout:
// In your model's toSearchableArray()
return $this->searchClient->prepareForSearch($this->attributesToArray());
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);
Async Processing Use Laravel Queues to offload index updates:
SyncDocuments::dispatch('products', $documents)->onQueue('search');
Engine-Specific Quirks
attributesForFaceting instead of facets.primaryKey in index settings.config/search-client.php for engine-specific defaults and override as needed.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
}
}
Data Serialization
Ensure your model data is serializable (no closures, resources, or circular references). Use json_encode($data) to test.
Index Naming Collisions
Avoid reserved names (e.g., _users). Prefix indices with your app name (e.g., app_products).
Enable Logging
Add to config/search-client.php:
'debug' => env('SEARCH_DEBUG', false),
Logs will appear in storage/logs/laravel.log.
Raw API Calls Access the underlying engine client for debugging:
$rawResponse = $client->getEngine()->raw('search', ['index' => 'products', 'q' => 'laptop']);
Common Errors
createIndex first..env.Partial Updates
Use updateDocuments to modify existing records:
$client->updateDocuments('products', [
['id' => 1, 'name' => 'Updated Laptop'],
]);
Synonyms and Stop Words Configure in index settings:
$client->createIndex('products', [
'settings' => [
'synonyms' => ['laptop' => ['notebook']],
'stopWords' => ['the', 'and'],
],
]);
Performance
addDocuments to 1000 records per batch.Extension Points
BaseSearchEngine and register via the service provider.buildQuery in SearchClient for custom logic.Adimeo\SearchClient\Contracts\Transformer to map results to Eloquent models.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.
How can I help you explore Laravel packages today?