Пример #1
0
 /**
  * Rebuilds ES Index and deletes the old one,
  *
  * @param bool $deleteOld             If set, the old index will be deleted upon successful rebuilding
  * @param bool $cancelExistingRebuild If set, any indices that the write alias points to (except the live one)
  *                                    will be deleted before the new build starts
  */
 public function rebuildIndex($deleteOld = false, $cancelExistingRebuild = false)
 {
     $batchSize = $this->connection->getConnectionSettings()['bulk_batch_size'];
     try {
         if (false === $this->getUseAliases()) {
             throw new Exception('Index rebuilding is not supported, unless you use aliases');
         }
         try {
             // Make sure the index and both aliases are properly set
             $this->verifyIndexAndAliasesState();
         } catch (NoReadAliasException $e) {
             // Looks like the index doesn't exist, so try to create an empty one
             $this->createIndex();
             // Now again make sure that everything is setup correctly
             $this->verifyIndexAndAliasesState();
         } catch (IndexRebuildingException $e) {
             if ($cancelExistingRebuild) {
                 // Delete the partial indices currently being rebuilt
                 foreach ($e->getIndices() as $partialIndex) {
                     $this->getConnection()->getClient()->indices()->delete(['index' => $partialIndex]);
                 }
             } else {
                 // Rethrow exception
                 throw $e;
             }
         }
         // Create a new index
         $settings = $this->indexMapping;
         $oldIndex = $this->getLiveIndex();
         $newIndex = $this->getUniqueIndexName();
         $settings['index'] = $newIndex;
         $this->getConnection()->getClient()->indices()->create($settings);
         // Point write alias to the new index as well
         $setAliasParams = ['body' => ['actions' => [['add' => ['index' => $newIndex, 'alias' => $this->writeAlias]]]]];
         $this->getConnection()->getClient()->indices()->updateAliases($setAliasParams);
         // Temporarily override the write alias with the new physical index name, so rebuilding only happens in the new index
         $originalWriteAlias = $this->writeAlias;
         $this->setWriteAlias($settings['index']);
         // Get and cycle all types for the index
         $indexDocumentsMetadata = $this->metadataCollector->getDocumentsMetadataForIndex($this->managerName);
         $documentClasses = array_keys($indexDocumentsMetadata);
         // Make sure we don't autocommit on every item in the bulk request
         $autocommit = $this->getConnection()->isAutocommit();
         $this->getConnection()->setAutocommit(false);
         foreach ($documentClasses as $documentClass) {
             $typeDataProvider = $this->getDataProvider($documentClass);
             $i = 1;
             foreach ($typeDataProvider->getDocuments() as $document) {
                 if (is_array($document)) {
                     $this->persistRaw($documentClass, $document);
                 } else {
                     $this->persist($document);
                 }
                 // Send the bulk request every X documents, so it doesn't get too big
                 if ($i % $batchSize == 0) {
                     $this->getConnection()->commit();
                 }
                 $i++;
             }
         }
         // Save any remaining documents to ES
         $this->getConnection()->commit();
         // Recover the autocommit mode as it was
         $this->getConnection()->setAutocommit($autocommit);
         // Restore write alias name
         $this->setWriteAlias($originalWriteAlias);
         // Point both aliases to the new index and remove them from the old
         $setAliasParams = ['body' => ['actions' => [['add' => ['index' => $newIndex, 'alias' => $this->readAlias]], ['remove' => ['index' => $oldIndex, 'alias' => $this->readAlias]], ['remove' => ['index' => $oldIndex, 'alias' => $this->writeAlias]]]]];
         $this->getConnection()->getClient()->indices()->updateAliases($setAliasParams);
         // Delete the old index
         if ($deleteOld) {
             $this->getConnection()->getClient()->indices()->delete(['index' => $oldIndex]);
             $this->getConnection()->getLogger()->notice(sprintf('Deleted old index %s', $oldIndex));
         }
     } catch (Exception $e) {
         // Bulk exceptions are logged in the connection manager, so only log other exceptions here
         if (!$e instanceof BulkRequestException) {
             $this->getConnection()->getLogger()->error($e->getMessage());
         }
         // Try to delete the new incomplete index
         if (isset($newIndex)) {
             $this->getConnection()->getClient()->indices()->delete(['index' => $newIndex]);
             $this->getConnection()->getLogger()->notice(sprintf('Deleted incomplete index "%s"', $newIndex));
         }
         // Rethrow exception to be further handled
         throw $e;
     }
 }