'index_name'] */ private $indexNameByStore = []; public function __construct( IndexNameResolver $indexNameResolver, ClientRepositoryInterface $clientRepository, IndexBuilderInterface $indexBuilder, EntityStructureBuilder $entityStructureBuilder, FieldMappingBuilderInterface $fieldMappingBuilder, DataMapperResolverInterface $dataMapperResolver, SaveQueryBuilderInterface $saveQueryBuilder, Debug $debug, ?ClientInterface $client = null ) { $this->indexNameResolver = $indexNameResolver; $this->clientRepository = $clientRepository; $this->indexBuilder = $indexBuilder; $this->entityStructureBuilder = $entityStructureBuilder; $this->fieldMappingBuilder = $fieldMappingBuilder; $this->dataMapperResolver = $dataMapperResolver; $this->saveQueryBuilder = $saveQueryBuilder; $this->debug = $debug; $this->client = $client; } public function prepareDocuments(array $documentData, int $storeId, string $indexerId): array { $documents = []; if (!empty($documentData)) { $documents = $this->dataMapperResolver->mapEntityData( $documentData, $storeId, ['indexer_id' => $indexerId] ); } return $documents; } public function saveDocuments(array $documents, int $storeId, string $indexerId): void { if (!empty($documents)) { try { $indexName = $this->indexNameResolver->getIndexName($indexerId, $storeId, $this->indexNameByStore); if ($this->getClient()->indexExists($indexName)) { $query = $this->saveQueryBuilder->execute($documents, $indexName); $this->getClient()->bulkQuery($query); } } catch (Exception $e) { $this->debug->debug($e); throw $e; } } } public function deleteDocuments(array $documentIds, int $storeId, string $indexerId): void { try { $indexName = $this->indexNameResolver->getIndexName($indexerId, $storeId, $this->indexNameByStore); if (!$this->getClient()->indexExists($indexName)) { return; } $query = $this->saveQueryBuilder->execute( $documentIds, $indexName, SaveQueryBuilderInterface::BULK_ACTION_DELETE ); $this->getClient()->bulkQuery($query); } catch (Exception $e) { $this->debug->debug($e); throw $e; } } public function cleanIndex(int $storeId, string $indexerId): void { // needed to fix bug with double indices in alias because of second reindex in same process unset($this->indexNameByStore[$storeId]); $this->checkIndex($storeId, $indexerId); $indexName = $this->indexNameResolver->getIndexName($indexerId, $storeId, $this->indexNameByStore); if ($this->getClient()->isEmptyIndex($indexName)) { return; } $indexPattern = $this->indexNameResolver->getIndexAlias($indexerId, $storeId) . '_v'; $version = (int)(str_replace($indexPattern, '', $indexName)); $newIndexName = $indexPattern . (++$version); if ($this->getClient()->indexExists($newIndexName)) { $this->getClient()->deleteIndex($newIndexName); } $this->prepareIndex($storeId, $newIndexName, $indexerId); } public function checkIndex(int $storeId, string $indexerId): void { $indexName = $this->indexNameResolver->getIndexName($indexerId, $storeId, $this->indexNameByStore); if (!$this->getClient()->indexExists($indexName)) { $this->prepareIndex($storeId, $indexName, $indexerId); } $alias = $this->indexNameResolver->getIndexAlias($indexerId, $storeId); if (!$this->getClient()->existsAlias($alias, $indexName)) { $this->getClient()->updateAlias($alias, $indexName); } } public function updateAlias(int $storeId, string $indexerId): void { if (!isset($this->indexNameByStore[$storeId])) { return; } $alias = $this->indexNameResolver->getIndexAlias($indexerId, $storeId); $oldIndex = $this->indexNameResolver->getIndexNameByAlias($alias, $storeId, $this->indexNameByStore); if (!empty($oldIndex)) { $params['body']['actions'][] = ['remove' => ['alias' => $alias, 'index' => $oldIndex]]; } $params['body']['actions'][] = ['add' => ['alias' => $alias, 'index' => $this->indexNameByStore[$storeId]]]; $this->getClient()->updateAliases($params); if ($oldIndex) { $this->getClient()->deleteIndex($oldIndex); } } public function ping(): bool { return $this->getClient()->ping(); } private function prepareIndex(int $storeId, string $indexName, string $indexerId): void { $this->indexBuilder->setStoreId($storeId); $this->getClient()->createIndex($indexName, $this->indexBuilder->build()); $mappingData = $this->fieldMappingBuilder->execute( $indexName, $storeId, $this->entityStructureBuilder->build($indexerId) ); $this->getClient()->putMapping($mappingData); $this->indexNameByStore[$storeId] = $indexName; } private function getClient(): ClientInterface { if ($this->client === null) { $this->client = $this->clientRepository->get(); } return $this->client; } }