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

Elastic Client Laravel Package

babenkoivan/elastic-client

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require babenkoivan/elastic-client
    

    Publish the config file:

    php artisan vendor:publish --provider="Babenkoivan\ElasticClient\ElasticClientServiceProvider" --tag="config"
    
  2. Configuration: Edit config/elastic.php to match your Elasticsearch cluster settings:

    'connections' => [
        'default' => [
            'hosts' => ['http://localhost:9200'],
            'username' => env('ELASTIC_USERNAME'),
            'password' => env('ELASTIC_PASSWORD'),
        ],
    ],
    
  3. First Use Case: Index a model (e.g., Post) in AppServiceProvider@boot():

    use Babenkoivan\ElasticClient\ElasticClient;
    
    public function boot()
    {
        ElasticClient::index('posts', Post::class);
    }
    
  4. Basic Query:

    $results = ElasticClient::search('posts', [
        'query' => [
            'match' => ['title' => 'Laravel']
        ]
    ]);
    

Implementation Patterns

Core Workflows

1. Model Integration

  • Auto-indexing: Use ElasticClient::index() in a service provider to sync models to Elasticsearch.
  • Dynamic Mapping: Leverage Laravel's $casts to define Elasticsearch field types:
    protected $casts = [
        'published_at' => 'date',
        'is_active' => 'boolean',
    ];
    

2. Query Patterns

  • Full-text search:
    ElasticClient::search('posts', [
        'query' => ['match' => ['content' => 'search term']]
    ]);
    
  • Aggregations:
    ElasticClient::search('posts', [
        'aggs' => [
            'tags' => ['terms' => ['field' => 'tags.keyword']]
        ]
    ]);
    
  • Pagination:
    ElasticClient::search('posts', [
        'from' => 0,
        'size' => 10,
        'query' => [...]
    ]);
    

3. Data Sync

  • Bulk Indexing:
    ElasticClient::bulkIndex('posts', Post::all()->toArray());
    
  • Partial Updates:
    ElasticClient::update('posts', $postId, ['title' => 'Updated Title']);
    

4. Laravel Integration

  • Service Container Binding: Bind the client in AppServiceProvider for dependency injection:
    $this->app->singleton(ElasticClient::class, function ($app) {
        return new ElasticClient(config('elastic.connections.default'));
    });
    
  • Query Builder Extensions: Extend Laravel's query builder to support Elasticsearch:
    use Babenkoivan\ElasticClient\Query\Builder;
    
    $results = Builder::for('posts')
        ->where('title', 'like', 'Laravel')
        ->paginate(10);
    

Advanced Patterns

1. Custom Analyzers

Define analyzers in config/elastic.php:

'analyzers' => [
    'custom_analyzer' => [
        'type' => 'custom',
        'tokenizer' => 'standard',
        'filter' => ['lowercase', 'asciifolding']
    ],
],

Apply to a field in your model:

ElasticClient::index('posts', Post::class, [
    'properties' => [
        'title' => [
            'type' => 'text',
            'analyzer' => 'custom_analyzer'
        ]
    ]
]);

2. Real-time Sync with Events

Listen for model events to sync changes:

Post::saved(function ($post) {
    ElasticClient::update('posts', $post->id, $post->toArray());
});

3. Multi-tenancy

Use connection switching for tenant-specific indices:

ElasticClient::connection('tenant_' . $tenantId)->search('posts', [...]);

4. Caching Responses

Cache frequent queries using Laravel's cache:

$cacheKey = 'elastic_posts_' . md5(serialize($query));
return Cache::remember($cacheKey, now()->addHours(1), function () use ($query) {
    return ElasticClient::search('posts', $query);
});

Gotchas and Tips

Pitfalls

  1. Mapping Conflicts:

    • Elasticsearch mappings are immutable by default. Avoid changing field types after indexing.
    • Fix: Use ?ignore=400 in the connection config to suppress mapping errors during updates.
  2. Bulk Operations:

    • Large bulk operations may time out. Use ?refresh=wait_for to control indexing delays.
    • Tip: Batch operations into chunks of 1,000-5,000 documents.
  3. Connection Issues:

    • Elasticsearch may reject connections if authentication fails silently.
    • Debug: Enable logging in config/elastic.php:
      'log' => [
          'enabled' => true,
          'level' => 'debug',
      ],
      
  4. Field Type Mismatches:

    • Laravel's $casts may not align with Elasticsearch types (e.g., string vs. text).
    • Solution: Explicitly define mappings in ElasticClient::index().
  5. Rate Limiting:

    • Elasticsearch may throttle requests. Use the scroll API for large datasets:
      $scroll = ElasticClient::scroll('posts', '1m', 1000);
      

Debugging Tips

  1. Raw Responses: Access raw Elasticsearch responses for debugging:

    $response = ElasticClient::raw('posts/_search', ['body' => $query]);
    
  2. Explain Queries: Use _explain to debug relevance scores:

    ElasticClient::explain('posts', $postId, [
        'query' => ['match' => ['content' => 'search term']]
    ]);
    
  3. Profile Queries: Enable profiling in queries:

    ElasticClient::search('posts', [
        'profile' => true,
        'query' => [...]
    ]);
    

Extension Points

  1. Custom Clients: Extend the base client for domain-specific logic:

    class CustomElasticClient extends \Babenkoivan\ElasticClient\ElasticClient
    {
        public function customMethod()
        {
            return $this->search('index', [...]);
        }
    }
    
  2. Middleware: Add middleware to transform requests/responses:

    ElasticClient::extend(function ($client) {
        $client->before(function ($request) {
            // Modify request
        });
    });
    
  3. Event Listeners: Listen for Elasticsearch events (e.g., index creation):

    ElasticClient::listen('index.created', function ($event) {
        logger()->info("Index {$event->index} created.");
    });
    

Performance Tips

  1. Index Aliases: Use aliases for zero-downtime reindexing:

    ElasticClient::alias('posts', 'posts_v2');
    
  2. Index Settings: Optimize for read-heavy workloads:

    ElasticClient::indexSettings('posts', [
        'number_of_replicas' => 0,
        'refresh_interval' => '30s'
    ]);
    
  3. Bulk API: Prefer _bulk over individual _create/_update calls for batch operations.

  4. Connection Pooling: Reuse connections for high-throughput applications:

    $client = ElasticClient::connection('default');
    // Reuse $client across requests
    

Configuration Quirks

  1. SSL/TLS: Configure SSL in config/elastic.php:

    'ssl' => [
        'verification_mode' => 'none', // or 'full', 'host', 'peer'
        'ca' => storage_path('certs/ca.pem'),
        'cert' => storage_path('certs/client.crt'),
        'key' => storage_path('certs/client.key'),
    ],
    
  2. Sniffing: Enable host sniffing for dynamic clusters:

    'sniff_on_start' => true,
    'sniff_on_connection_fail' => true,
    
  3. Environment Variables: Use Laravel's .env for sensitive data:

    ELASTIC_HOSTS=http://localhost:9200
    ELASTIC_USERNAME=admin
    ELASTIC_PASSWORD=secret
    

    Reference in config:

    'hosts' => explode(',', env('ELASTIC_HOSTS')),
    

Testing Strategies

  1. Mocking: Use
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle