creatortsv / eloquent-elastic-sync
This package helps sync indexing your eloquent models into elasticsearch
Installs: 5 002
Dependents: 0
Suggesters: 0
Security: 0
Stars: 0
Watchers: 1
Forks: 0
Open Issues: 0
pkg:composer/creatortsv/eloquent-elastic-sync
Requires
- php: >=7.2.0
- guzzlehttp/guzzle: >=6.3
- guzzlehttp/psr7: >=1.5
- illuminate/console: >=5.6.0
- illuminate/database: >=5.6.0
- illuminate/http: >=5.6.0
- illuminate/support: >=5.6.0
Requires (Dev)
- fzaninotto/faker: >=1.4
- mockery/mockery: >=0.9
- phpunit/phpunit: >=7
This package is auto-updated.
Last update: 2025-10-12 17:43:18 UTC
README
This package helps you to sync your eloquent models with elasticsearch documents
Prerequisites
PHP >= 7.2
Installation
- Run composer command:
composer require creatortsv/eloquent-elastic-sync
- Add
EloquentObservanttrait to your eloquent models which will be syncronized with elasticsearch:
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { /* ... */ use EloquentObservant; /* ... */ }
Configuration
You may want to create config/elastic_sync.php config file or import it from the package using this artisan command
php artisan vendor:publish --provider="Creatortsv\EloquentElasticSync\EloquentElasticSyncProvider"
For the minimum configuration You should edit host and port properties of the connections.default section of your config/elastic_sync.php config file:
<?php return [ /* * Describe different connections */ 'connections' => [ /* * Connection name */ 'default' => [ 'host' => env('ELASTIC_HOST'), 'port' => env('ELASTIC_PORT'), ], ], ];
If You want to use another connection by default then describe your own connection into the connections section and change the connection property of the config/elastyc_sync.php file:
<?php return [ /* * Which connection settings will be used */ 'connection' => 'awesome_connection', // default /* * Describe different connections */ 'connections' => [ /* ... */ 'awesome_connection' => [ 'host' => 'awesome.com', 'port' => 9201, ], /* ... */ ], ];
If You want to use different connections for your eloquent models:
- Describe your own connections for some eloquent models into the
connectionssection of theconfig/elastyc_sync.phpfile
<?php return [ /* * Describe different connections */ 'connections' => [ /* ... */ 'flights-connection' => [ 'host' => 'awesome.users.com', 'port' => 9202, ], /* ... */ ], ];
- Override the
php protected static function boot(): voidmethod into your Eloquent models and set connection name like this
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { use EloquentObservant; protected static function boot(): void { parent::boot(); static::elastic()->setConnection('flights-connection'); } /* ... */ }
Data mapping
By default an Eloquent model will be syncronized to the Elasticsearch document with its own attributes (without relations). But if You want to sync models with mutated attributus, for example:
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { use EloquentObservant; /* ... */ /** * Get full name of the flight * @return string */ public function getFlightNameAttribute(): string { return $this->name . ' ' . $this->destination; } /* ... */ }
Then You should change the use_mutated_fields property of your config/elastic_sync.php file to true
<?php return [ /* ... */ 'use_mutated_fields' => true, /* ... */ ];
You can use your own data mapping and index name for your Eloquent models, this data will be used for interacting with Elasticserch index|update|delete actions.
By default Index name for Eloquent models (if indexes.default property is null) is equal to the table name property of the Model.
You can do it with two different ways:
- Describe a data mapping into
indexessection of theconfig/elastyc_sync.phpfile and set thedefaultoption. Also Data mapping may be described for every single Model
<?php return [ /* ... */ /* * Describe different indexes & its fields */ 'indexes' => [ 'default' => 'my-index', // if it is null then attributes of model will be used /** * Index name it'll bwe used as index for the documents */ 'my-index' => [ /** * Base mapping for models */ 'base_mapping' => [ 'id', 'name, /** 'avatar' => 'avatar.safe_url', Dot anotation allowed for the relations */ ], App\Flight::class => [ /* ... This mapping will be merged with the base_mapping of the described index */ ], ], ], /* ... */ ];
- Configure it behavior with
boot()method on your Eloquent models
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { use EloquentObservant; /* ... */ protected static function boot(): void { parent::boot(); /** * Use custom data mapping * Don't use real data, only field names */ static::elastic()->setMapping(function (Model $model): array { return [ /* Describe yor mapping here */ ]; }); /** * This name will be used as index for the Elasticsearch document */ static::elastic()->setIndexName('flights-index'); } /* ... */ }
For each Eloquent model class You can add Extra fields for the indexing document, like this
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { use EloquentObservant; /* ... */ protected static function boot(): void { parent::boot(); /** * Using callback */ static::elastic()->addExtra('group', function (Model $model): array { return $model->getTable(); }); /** * Using simple assign action */ static::elastic()->addExtra('my_field', 'my_value'); } /* ... */ }
Also You can modify fields and extra fields before send it to the Elasticsearch document with callback functions, like this
<?php namespace App; use Illuminate\Database\Eloquent\Model; use Creatortsv\EloquentElasticSync\EloquentObservant; class Flight extends Model { use EloquentObservant; /* ... */ protected static function boot(): void { parent::boot(); /** * Modify group extra field for example * @param mixed $group It is value after data mapping operation * @param array $data All data values after data mapping operation */ static::elastic()->addCallback('group', function ($group, array $data, Model $model) { return $group . ' company: ' . $model->company->name; // result: flights company: Some Company Name }); /** * Another time */ static::elastic()->addCallback('group', function ($group, array $data, Model $model) { return $group . ' fixed'; // result: flights company: Some Company Name fixed }); } /* ... */ }
Artisan Command
Work in progress ...