shader2k / search-indexer
zero downtime reindex
Requires
- php: ^7.1 || ^8.0
- ext-json: *
- hassankhan/config: ^2.1
- vlucas/phpdotenv: ^3.6
Requires (Dev)
- mockery/mockery: ^1.0
- phpunit/phpunit: ^8
This package is auto-updated.
Last update: 2024-11-04 20:30:13 UTC
README
Elasticsearch zero downtime reindexing
Переиндексация модели с нулевым временем простоя
Установка
Установка через Composer
composer require shader2k/search-indexer
Настройка
Скопировать config файл в <projectRoot>/config/indexerconfig.php
Параметры конфигурации:
searchDriverFactories
иdataProviderFactories
- доступные в системе драйвера и провайдеры (можно расширять имеющиеся, указав алиасы и классы фабрик)searchDriverNameDefault
иdataProviderNameDefault
- алиасы драйвера и провайдера по умолчаниюdataProviderChunkSize
размер частей для получения данных из моделиelasticsearchHost
хост поискового движка (ElasticSearch)
При необходимости можно разместить .env файл в корень проекта (.env.example)
Использование
Индексируемая модель должна обязательно имплементировать интерфейс \Indexable\IndexableContract
Реализуемые методы:
-
getIndexableFields()
должен вернуть массив имен полей, которые небоходимо добавить в индекс -
getIdentifierField()
должен вернуть имя поля, используемое в качестве ID -
getSearchDriverName()
если метод вернет null, будет использован драйвер по умолчанию. Если указать имя драйвера, для индексирования будет использован этот драйвер -
getProviderName()
имя провайдера. Используется аналогично методуgetSearchDriverName()
-
getIndexName()
имя индекса (должно быть уникально), напримерreturn __CLASS__;
-
getIdentifierValue()
значение ID, напримерreturn (string) $this->id;
В пакете присутствует трейт Traits\IndexableTrait
, который можно использовать в моделях для использования драйвера и провайдера по умолчанию.
Использование сервиса в проекте
Инициализировать сервис желательно как синглтон
indexingModel()
переиндексация всей модели. В данном случае будет создан новый индекс, в него проиндексируется модель, затем, атомарной операцией, старый индекс будет подменен новым.indexingEntity()
добавить одну сущность в индексremoveEntity()
удаление сущности из индекса
$searchIndexer = new SearchIndexerService(new ProviderManager(), new DriverManager()); //переиндексация всей модели $searchIndexer->indexingModel(User::class); //переиндексация одной сущности $index = $searchIndexer->indexingEntity($entity); //удаление одной сущности $index = $searchIndexer->removeEntity($entity);
Добавление сервиса в проект на Laravel
В методе boot()
AppServiceProvider.php нужно объявить сервис как синглтон
$this->app->singleton('SearchIndexerService', function ($app) { return new SearchIndexerService(new ProviderManager(), new DriverManager()); });
Использование сервиса:
$indexerService = App::make('SearchIndexerService'); //переиндексация всей модели $indexerService->indexingModel(User::class); //переиндексация одной сущности $index = $indexerService->indexingEntity($entity); //удаление одной сущности $index = $indexerService->removeEntity($entity);
Расширение пакета
Возможно расширение пакета за счет дополнительных драйверов для поисковых движков (например Sphinx, Elasticsearch) и провайдеров данных (например Eloquent, Doctrine)
Расширения можно найти по ссылкам: Драйвера для поисковых машин, Провайдеры данных
Добавление драйвера:
Необходимо реализовать интерфейс фабрики для драйвера DriverFactoryContract
и интерфейс драйвера DriverContract
.
Добавить новый драйвер в config:
'searchDriverFactories' => [ 'anyAlias' => '\YourRepository\DriverFactoryClass' ]
При реализации метода prepareIndex
драйвера, необходимо обеспечить бесперебойную работу старого индекса, в случае переиндексации всей модели
(на что указывает параметр $reindex
со значением true
).
После переиндексации - атомарной операцией подменить старый индекс на новый.
Аналогично можно расширить провайдеры, реализуя ProviderFactoryContract
для фабрики и ProviderContract
для провайдера.
Добавить новый провайдер в config:
'dataProviderFactories' => [ 'anyAlias' => '\YourRepository\ProviderFactoryClass' ]