FEATURE: Provide command to delete whole index

This is necessary, e.g. for complete re-indexing.
This commit is contained in:
Daniel Siepmann 2017-11-10 13:22:15 +01:00
parent ea8eb8148e
commit a3a46f5cb5
Signed by: Daniel Siepmann
GPG key ID: 33D6629915560EF4
8 changed files with 152 additions and 3 deletions

View file

@ -50,7 +50,6 @@ class IndexCommandController extends CommandController
*/ */
public function indexCommand($identifier) public function indexCommand($identifier)
{ {
// TODO: Also allow to index everything?
try { try {
$this->indexerFactory->getIndexer($identifier)->indexAllDocuments(); $this->indexerFactory->getIndexer($identifier)->indexAllDocuments();
$this->outputLine($identifier . ' was indexed.'); $this->outputLine($identifier . ' was indexed.');
@ -58,4 +57,19 @@ class IndexCommandController extends CommandController
$this->outputLine('No indexer found for: ' . $identifier); $this->outputLine('No indexer found for: ' . $identifier);
} }
} }
/**
* Will delete the given identifier.
*
* @param string $identifier
*/
public function deleteCommand($identifier)
{
try {
$this->indexerFactory->getIndexer($identifier)->delete();
$this->outputLine($identifier . ' was deleted.');
} catch (NoMatchingIndexerException $e) {
$this->outputLine('No indexer found for: ' . $identifier);
}
}
} }

View file

@ -77,4 +77,13 @@ interface ConnectionInterface
* @return SearchResultInterface * @return SearchResultInterface
*/ */
public function search(SearchRequestInterface $searchRequest); public function search(SearchRequestInterface $searchRequest);
/**
* Will delete the whole index / db.
*
* @param string $documentType
*
* @return void
*/
public function deleteIndex($documentType);
} }

View file

@ -156,6 +156,18 @@ class Elasticsearch implements Singleton, ConnectionInterface
); );
} }
public function deleteIndex($documentType)
{
$index = $this->connection->getClient()->getIndex('typo3content');
if (! $index->exists()) {
$this->logger->notice('Index did not exist, therefore was not deleted.', [$documentType, 'typo3content']);
return;
}
$index->delete();
}
/** /**
* Execute given callback with Elastica Type based on provided documentType * Execute given callback with Elastica Type based on provided documentType
* *

View file

@ -104,6 +104,13 @@ abstract class AbstractIndexer implements IndexerInterface
$this->logger->info('Finish indexing'); $this->logger->info('Finish indexing');
} }
public function delete()
{
$this->logger->info('Start deletion of index.');
$this->connection->deleteIndex($this->getDocumentName());
$this->logger->info('Finish deletion.');
}
/** /**
* @return \Generator * @return \Generator
*/ */

View file

@ -33,9 +33,9 @@ interface IndexerInterface
public function indexAllDocuments(); public function indexAllDocuments();
/** /**
* Fetches a single document from the indexerService and pushes it to the connection. * Fetches a single document and pushes it to the connection.
* *
* @param string $identifier identifier, the indexer needs to identify a single document * @param string $identifier
* *
* @return void * @return void
*/ */
@ -49,4 +49,11 @@ interface IndexerInterface
* @return void * @return void
*/ */
public function setIdentifier($identifier); public function setIdentifier($identifier);
/**
* Delete the whole index.
*
* @return void
*/
public function delete();
} }

View file

@ -18,6 +18,19 @@ This will index the table ``tt_content`` using the :ref:`TcaIndexer`.
Only one index per call is available, to run multiple indexers, just make multiple calls. Only one index per call is available, to run multiple indexers, just make multiple calls.
The indexers have to be defined in TypoScript via :ref:`configuration_options_index`. The indexers have to be defined in TypoScript via :ref:`configuration_options_index`.
.. _usage_manual_deletion:
Manual deletion
---------------
You can trigger deletion for a single index from CLI::
./typo3/cli_dispatch.phpsh extbase index:delete --identifier 'tt_content'
This will delete the index for the table ``tt_content``.
Only one delete per call is available, to run multiple deletions, just make multiple calls.
.. _usage_auto_indexing: .. _usage_auto_indexing:
Auto indexing Auto indexing

View file

@ -0,0 +1,50 @@
<?php
namespace Codappix\SearchCore\Tests\Functional\Connection\Elasticsearch;
/*
* Copyright (C) 2016 Daniel Siepmann <coding@daniel-siepmann.de>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
* 02110-1301, USA.
*/
use Codappix\SearchCore\Domain\Index\IndexerFactory;
use TYPO3\CMS\Extbase\Object\ObjectManager;
class IndexDeletionTest extends AbstractFunctionalTestCase
{
/**
* @test
*/
public function indexIsDeleted()
{
$this->client->getIndex('typo3content')->create();
$this->assertTrue(
$this->client->getIndex('typo3content')->exists(),
'Could not create index for test.'
);
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(ObjectManager::class)
->get(IndexerFactory::class)
->getIndexer('tt_content')
->delete()
;
$this->assertFalse(
$this->client->getIndex('typo3content')->exists(),
'Index could not be deleted through command controller.'
);
}
}

View file

@ -91,4 +91,41 @@ class IndexCommandControllerTest extends AbstractUnitTestCase
$this->subject->indexCommand('allowedTable'); $this->subject->indexCommand('allowedTable');
} }
/**
* @test
*/
public function deletionIsPossible()
{
$indexerMock = $this->getMockBuilder(TcaIndexer::class)
->disableOriginalConstructor()
->getMock();
$this->subject->expects($this->once())
->method('outputLine')
->with('allowedTable was deleted.');
$this->indexerFactory->expects($this->once())
->method('getIndexer')
->with('allowedTable')
->will($this->returnValue($indexerMock));
$indexerMock->expects($this->once())
->method('delete');
$this->subject->deleteCommand('allowedTable');
}
/**
* @test
*/
public function deletionForNonExistingIndexerDoesNotWork()
{
$this->subject->expects($this->once())
->method('outputLine')
->with('No indexer found for: nonAllowedTable');
$this->indexerFactory->expects($this->once())
->method('getIndexer')
->with('nonAllowedTable')
->will($this->throwException(new NoMatchingIndexerException));
$this->subject->deleteCommand('nonAllowedTable');
}
} }