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)
{
// TODO: Also allow to index everything?
try {
$this->indexerFactory->getIndexer($identifier)->indexAllDocuments();
$this->outputLine($identifier . ' was indexed.');
@ -58,4 +57,19 @@ class IndexCommandController extends CommandController
$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
*/
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
*

View file

@ -104,6 +104,13 @@ abstract class AbstractIndexer implements IndexerInterface
$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
*/

View file

@ -33,9 +33,9 @@ interface IndexerInterface
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
*/
@ -49,4 +49,11 @@ interface IndexerInterface
* @return void
*/
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.
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:
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');
}
/**
* @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');
}
}