This guide covers the breaking changes and migration steps required when upgrading from matchory/elasticsearch v2.x to v3.0.
The Query class has been renamed to Builder for consistency with Laravel Eloquent naming conventions.
Before (v2.x):
use Matchory\Elasticsearch\Query;
$query = new Query($connection);
$query->where('status', 'active');
// Type hints
public function scopeActive(Query $query): Query
{
return $query->where('active', true);
}After (v3.0):
use Matchory\Elasticsearch\Builder;
$builder = new Builder($connection);
$builder->where('status', 'active');
// Type hints
public function scopeActive(Builder $builder): Builder
{
return $builder->where('active', true);
}The following deprecated static methods have been removed from Connection:
Connection::setConnectionResolver()- Use dependency injection insteadConnection::configureLogging()- Configure logging via config fileConnection::create()- UseConnectionManagerto get connectionsConnection::connection()- UseConnectionManager::connection()insteadConnection::isLoaded()- No longer needed
Before (v2.x):
use Matchory\Elasticsearch\Connection;
$connection = Connection::create(['hosts' => ['localhost:9200']]);After (v3.0):
use Matchory\Elasticsearch\Interfaces\ConnectionResolverInterface;
// Via dependency injection
public function __construct(ConnectionResolverInterface $resolver)
{
$connection = $resolver->connection();
}
// Or via facade
$connection = Elasticsearch::connection();The deprecated Request class has been removed entirely. Use the Builder class for all query operations.
The Bulk class has been moved from Matchory\Elasticsearch\Classes\Bulk to Matchory\Elasticsearch\Bulk.
Before (v2.x):
use Matchory\Elasticsearch\Classes\Bulk;After (v3.0):
use Matchory\Elasticsearch\Bulk;The deprecated es.php config file is no longer supported. Rename your config file to elasticsearch.php.
Before (v2.x):
config/es.php
After (v3.0):
config/elasticsearch.php
The es container alias has been removed. Use elasticsearch instead.
Before (v2.x):
$connection = app('es');After (v3.0):
$connection = app('elasticsearch');
// Or better, use the interface
$resolver = app(ConnectionResolverInterface::class);
$connection = $resolver->connection();The getConnection() and setConnection() methods on Model have been removed. Use the renamed methods instead:
Before (v2.x):
$model->setConnection('analytics');
$connectionName = $model->getConnection();After (v3.0):
$model->setConnectionName('analytics');
$connectionName = $model->getConnectionName();The Index class callback constructor parameter has been removed. Use the fluent builder pattern instead:
Before (v2.x):
ES::createIndex('posts', function ($index) {
$index->shards(3)->replicas(1)->mapping([...]);
});After (v3.0):
ES::newIndex('posts')
->shards(3)
->replicas(1)
->mapping([...])
->create();The following properties in Index are now private (use getter methods):
$ignores- UsegetIgnores()orignores()to modify$mappings- Use appropriate methods$name- UsegetName()$settings- Use appropriate methods$aliases- Use appropriate methods
The Scout engine now uses ConnectionManager for client creation, which means:
- Authentication settings from your config are now respected
- SSL/TLS settings are properly applied
- Logging configuration works correctly
Configure your Scout connection in config/scout.php:
'elasticsearch' => [
'connection' => 'default', // Name of your Elasticsearch connection
'index' => 'scout',
],Check if your Elasticsearch connection is healthy:
if ($connection->ping()) {
// Connection is healthy
}Configure automatic retry with exponential backoff:
$results = Model::query()
->retry(attempts: 3, delay: 100)
->where('status', 'active')
->get();Batch large bulk operations to avoid memory issues:
// Automatically chunks into batches of 500
$builder->bulk($documents, batchSize: 500);Enable Elasticsearch query profiling for debugging:
$results = Model::query()
->profile()
->where('status', 'active')
->get();Scout now uses simple_query_string instead of query_string for safer handling of user input without throwing exceptions on special characters.
Cache keys now include the application key for improved security and unpredictability.
You can now use orWhere() to add OR conditions to your queries:
// Find documents where status is "published" OR "featured"
Model::query()
->orWhere('status', 'published')
->orWhere('status', 'featured')
->get();
// Combine AND and OR conditions
Model::query()
->where('category', 'tech')
->orWhere('status', 'published')
->orWhere('status', 'featured')
->get();
// Control how many OR conditions must match
Model::query()
->orWhere('tag', 'php')
->orWhere('tag', 'laravel')
->orWhere('tag', 'elasticsearch')
->minimumShouldMatch(2)
->get();The new except() method provides a clearer way to exclude fields from results:
// Exclude sensitive fields
Model::query()->except('password', 'api_key')->get();
// Combine with select
Model::query()
->select('title', 'content', 'author')
->except('author.email')
->get();The limit() method is now available as an alias for take(), matching Laravel Eloquent's API:
Model::query()->limit(10)->get();The following methods are deprecated and will be removed in a future version:
The Elasticsearch-specific from() and size() methods are deprecated. Use skip() and take()/limit() instead for consistency with Laravel Eloquent:
Before (deprecated):
ES::index('my_index')->from(10)->size(20)->get();After:
ES::index('my_index')->skip(10)->take(20)->get();
// or
ES::index('my_index')->skip(10)->limit(20)->get();The unselect() method is deprecated. Use except() instead for better clarity:
Before (deprecated):
ES::index('my_index')->unselect('password', 'secret')->get();After:
ES::index('my_index')->except('password', 'secret')->get();Before upgrading to v3.0, ensure you've addressed these deprecations:
- Rename
Queryimports and type hints toBuilder - Replace static
Connectionmethod calls withConnectionManager - Rename your
es.phpconfig toelasticsearch.php - Replace
app('es')withapp('elasticsearch')or interface resolution - Update any code accessing
Indexproperties directly to use methods
- Update composer.json to require
matchory/elasticsearch: ^3.0 - Run
composer update matchory/elasticsearch - Search and replace
use Matchory\Elasticsearch\Querywithuse Matchory\Elasticsearch\Builder - Search and replace
use Matchory\Elasticsearch\Classes\Bulkwithuse Matchory\Elasticsearch\Bulk - Update type hints from
QuerytoBuilder - Rename
config/es.phptoconfig/elasticsearch.phpif applicable - Replace
app('es')withapp('elasticsearch') - Remove any usage of
Connection::create(),Connection::connection(), etc. - Replace
$model->getConnection()with$model->getConnectionName() - Replace
$model->setConnection()with$model->setConnectionName() - Update
createIndex()callbacks to use fluentnewIndex()builder - Update Scout config if using custom connection settings
- Run tests to verify everything works correctly