Elastic Migrations
Elasticsearch migrations for Laravel allow you to easily modify and share indices schema across the application's environments.
Contents
- Compatibility
- Installation
- Configuration
- Writing Migrations
- Running Migrations
- Reverting Migrations
- Starting Over
- Migration Status
- Zero Downtime Migration
- Troubleshooting
Compatibility
The current version of Elastic Migrations has been tested with the following configuration:
- PHP 7.2-8.0
- Elasticsearch 7.x
- Laravel 6.x-8.x
Installation
The library can be installed via Composer:
composer require babenkoivan/elastic-migrations
If you want to use Elastic Migrations with Lumen framework check this guide.
Configuration
Elastic Migrations uses babenkoivan/elastic-client as a dependency. If you want to change the default client settings (and I'm pretty sure you do), then you need to create the configuration file first:
php artisan vendor:publish --provider="ElasticClient\ServiceProvider"
You can change Elasticsearch host and other client settings in the config/elastic.client.php
file. Please refer to babenkoivan/elastic-client for more details.
If you want to change the migration table name, the default migrations directory or set prefixes for indices and aliases, publish Elastic Migrations settings as well:
php artisan vendor:publish --provider="ElasticMigrations\ServiceProvider"
The published configuration can be found in the config/elastic.migrations.php
file.
Finally, don't forget to run Laravel database migrations to create Elastic Migrations table:
php artisan migrate
Writing Migrations
You can effortlessly create a new migration file using an Artisan console command:
php artisan elastic:make:migration create_my_index
This command creates a migration class in the elastic/migrations
directory.
Every migration includes two methods: up
and down
. up
is used to alternate the index schema and down
is used to revert that action.
You can use ElasticMigrations\Facades\Index
facade to perform basic operations over Elasticsearch indices:
Create Index
Create an index with the default settings:
Index::create('my-index');
or use a modifier to configure mapping and settings:
Index::create('my-index', function (Mapping $mapping, Settings $settings) {
// to add a new field to the mapping use method name as a field type (in Camel Case),
// first argument as a field name and optional second argument as additional field parameters
$mapping->text('title', ['boost' => 2]);
$mapping->float('price');
// you can define a dynamic template as follows
$mapping->dynamicTemplate('my_template_name', [
'match_mapping_type' => 'long',
'mapping' => [
'type' => 'integer',
],
]);
// you can also change the index settings
$settings->index([
'number_of_replicas' => 2,
'refresh_interval' => -1
]);
// and analysis configuration
$settings->analysis([
'analyzer' => [
'title' => [
'type' => 'custom',
'tokenizer' => 'whitespace'
]
]
]);
});
There is also an option to create an index only if it doesn't exist:
Index::createIfNotExists('my-index');
Update Mapping
Use the modifier to adjust the mapping:
Index::putMapping('my-index', function (Mapping $mapping) {
$mapping->text('title', ['boost' => 2]);
$mapping->float('price');
});
Update Settings
Use the modifier to change the index configuration:
Index::putSettings('my-index', function (Settings $settings) {
$settings->index([
'number_of_replicas' => 2,
'refresh_interval' => -1
]);
});
You can update analysis settings only on closed indices. The putSettingsHard
method closes the index, updates the configuration and opens the index again:
Index::putSettingsHard('my-index', function (Settings $settings) {
$settings->analysis([
'analyzer' => [
'title' => [
'type' => 'custom',
'tokenizer' => 'whitespace'
]
]
]);
});
Drop Index
You can unconditionally delete the index:
Index::drop('my-index');
or delete it only if it exists:
Index::dropIfExists('my-index');
Create Alias
You can create an alias with optional filter query:
Index::putAlias('my-index', 'my-alias', ['term' => ['user_id' => 1]]);
Delete Alias
You can delete an alias by its name:
Index::deleteAlias('my-index', 'my-alias');
More
Finally, you are free to inject Elasticsearch\Client
in the migration constructor and execute any supported by client actions.
Running Migrations
You can either run all migrations:
php artisan elastic:migrate
or run a specific one:
php artisan elastic:migrate 2018_12_01_081000_create_my_index
Use the --force
option if you want to execute migrations on production environment:
php artisan elastic:migrate --force
Reverting Migrations
You can either revert the last executed migrations:
php artisan elastic:migrate:rollback
or rollback a specific one:
php artisan elastic:migrate:rollback 2018_12_01_081000_create_my_index
Use the elastic:migrate:reset
command if you want to revert all previously migrated files:
php artisan elastic:migrate:reset
Starting Over
Sometimes you just want to start over, rollback all the changes and apply them again:
php artisan elastic:migrate:refresh
Alternatively you can also drop all existing indices and rerun the migrations:
php artisan elastic:migrate:fresh
Migration Status
You can always check which files have been already migrated and what can be reverted by the elastic:migrate:rollback
command (the last batch):
php artisan elastic:migrate:status
Zero Downtime Migration
Changing an index mapping with zero downtime is not a trivial process and might vary from one project to another. Elastic Migrations library doesn't include such feature out of the box, but you can implement it in your project by following this guide.
Troubleshooting
If you see one of the messages below, follow the instructions:
Migration table is not yet created
- run thephp artisan migrate
commandMigration directory is not yet created
- create a migration file using theelastic:make:migration
command or createmigrations
directory manually
In case one of the commands doesn't work as expected, try to publish configuration:
php artisan vendor:publish --provider="ElasticMigrations\ServiceProvider"