mirror of
https://github.com/Codappix/search_core.git
synced 2024-11-23 11:56:10 +01:00
[!!!][FEATURE] Remap specific document type's to ES6 identifiers
Multiple types are not allowed any more in ES6. Refactored to use document type and custom identifier to still create different 'types'. See: https://www.elastic.co/guide/en/elasticsearch/reference/6.x/removal-of-types.html
This commit is contained in:
parent
397a91e9b0
commit
e297d556e6
6 changed files with 84 additions and 32 deletions
|
@ -23,6 +23,7 @@ namespace Codappix\SearchCore\Command;
|
||||||
|
|
||||||
use Codappix\SearchCore\Domain\Index\IndexerFactory;
|
use Codappix\SearchCore\Domain\Index\IndexerFactory;
|
||||||
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
|
use Codappix\SearchCore\Domain\Index\NoMatchingIndexerException;
|
||||||
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
|
use TYPO3\CMS\Extbase\Mvc\Controller\CommandController;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -52,12 +53,17 @@ class IndexCommandController extends CommandController
|
||||||
*/
|
*/
|
||||||
public function indexCommand(string $identifier)
|
public function indexCommand(string $identifier)
|
||||||
{
|
{
|
||||||
try {
|
// Allow multiple identifiers per import task
|
||||||
$this->indexerFactory->getIndexer($identifier)->indexAllDocuments();
|
$identifiers = GeneralUtility::trimExplode(',', $identifier, true);
|
||||||
$this->outputLine($identifier . ' was indexed.');
|
foreach ($identifiers as $value) {
|
||||||
} catch (NoMatchingIndexerException $e) {
|
try {
|
||||||
$this->outputLine('No indexer found for: ' . $identifier);
|
$this->indexerFactory->getIndexer($value)->indexAllDocuments();
|
||||||
|
$this->outputLine($value . ' was indexed.');
|
||||||
|
} catch (NoMatchingIndexerException $e) {
|
||||||
|
$this->outputLine('No indexer found for: ' . $value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -68,11 +74,15 @@ class IndexCommandController extends CommandController
|
||||||
*/
|
*/
|
||||||
public function deleteCommand(string $identifier)
|
public function deleteCommand(string $identifier)
|
||||||
{
|
{
|
||||||
try {
|
// Allow multiple identifiers per import task
|
||||||
$this->indexerFactory->getIndexer($identifier)->delete();
|
$identifiers = GeneralUtility::trimExplode(',', $identifier, true);
|
||||||
$this->outputLine($identifier . ' was deleted.');
|
foreach ($identifiers as $value) {
|
||||||
} catch (NoMatchingIndexerException $e) {
|
try {
|
||||||
$this->outputLine('No indexer found for: ' . $identifier);
|
$this->indexerFactory->getIndexer($value)->delete();
|
||||||
|
$this->outputLine($value . ' was deleted.');
|
||||||
|
} catch (NoMatchingIndexerException $e) {
|
||||||
|
$this->outputLine('No indexer found for: ' . $value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@ namespace Codappix\SearchCore\Connection;
|
||||||
* 02110-1301, USA.
|
* 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
use Elastica\Query;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines interface for connections to storage backend for interacting with documents.
|
* Defines interface for connections to storage backend for interacting with documents.
|
||||||
*/
|
*/
|
||||||
|
@ -77,8 +79,15 @@ interface ConnectionInterface
|
||||||
/**
|
/**
|
||||||
* Will delete the whole index / db.
|
* Will delete the whole index / db.
|
||||||
*
|
*
|
||||||
* @param string $documentType
|
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function deleteIndex(string $documentType);
|
public function deleteIndex();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Will delete the index / db of defined document type.
|
||||||
|
*
|
||||||
|
* @param Query $query
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleteIndexByQuery(Query $query);
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,8 +23,10 @@ namespace Codappix\SearchCore\Connection;
|
||||||
|
|
||||||
use Codappix\SearchCore\Connection\Elasticsearch\SearchResult;
|
use Codappix\SearchCore\Connection\Elasticsearch\SearchResult;
|
||||||
use Codappix\SearchCore\Domain\Search\QueryFactory;
|
use Codappix\SearchCore\Domain\Search\QueryFactory;
|
||||||
|
use Elastica\Query;
|
||||||
use TYPO3\CMS\Core\SingletonInterface as Singleton;
|
use TYPO3\CMS\Core\SingletonInterface as Singleton;
|
||||||
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface;
|
||||||
|
use TYPO3\CMS\Extbase\Utility\DebuggerUtility;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Outer wrapper to elasticsearch.
|
* Outer wrapper to elasticsearch.
|
||||||
|
@ -121,8 +123,8 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
{
|
{
|
||||||
$this->withType(
|
$this->withType(
|
||||||
$documentType,
|
$documentType,
|
||||||
function ($type) use ($document) {
|
function ($type) use ($documentType, $document) {
|
||||||
$type->addDocument($this->documentFactory->getDocument($type->getName(), $document));
|
$type->addDocument($this->documentFactory->getDocument($documentType, $document));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -156,8 +158,8 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
{
|
{
|
||||||
$this->withType(
|
$this->withType(
|
||||||
$documentType,
|
$documentType,
|
||||||
function ($type) use ($document) {
|
function ($type) use ($documentType, $document) {
|
||||||
$type->updateDocument($this->documentFactory->getDocument($type->getName(), $document));
|
$type->updateDocument($this->documentFactory->getDocument($documentType, $document));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -170,23 +172,23 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
{
|
{
|
||||||
$this->withType(
|
$this->withType(
|
||||||
$documentType,
|
$documentType,
|
||||||
function ($type) use ($documents) {
|
function ($type) use ($documentType, $documents) {
|
||||||
$type->addDocuments($this->documentFactory->getDocuments($type->getName(), $documents));
|
$type->addDocuments($this->documentFactory->getDocuments($documentType, $documents));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $documentType
|
* @return void
|
||||||
*/
|
*/
|
||||||
public function deleteIndex(string $documentType)
|
public function deleteIndex()
|
||||||
{
|
{
|
||||||
$index = $this->connection->getClient()->getIndex($this->indexFactory->getIndexName());
|
$index = $this->connection->getClient()->getIndex($this->indexFactory->getIndexName());
|
||||||
|
|
||||||
if (!$index->exists()) {
|
if (!$index->exists()) {
|
||||||
$this->logger->notice(
|
$this->logger->notice(
|
||||||
'Index did not exist, therefore was not deleted.',
|
'Index did not exist, therefore was not deleted.',
|
||||||
[$documentType, $this->indexFactory->getIndexName()]
|
[$this->indexFactory->getIndexName()]
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -194,6 +196,24 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
$index->delete();
|
$index->delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Query $query
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function deleteIndexByQuery(Query $query)
|
||||||
|
{
|
||||||
|
$index = $this->connection->getClient()->getIndex($this->indexFactory->getIndexName());
|
||||||
|
if (!$index->exists()) {
|
||||||
|
$this->logger->notice(
|
||||||
|
'Index did not exist, therefore items can not be deleted by query.',
|
||||||
|
[$this->indexFactory->getIndexName(), $query->getQuery()]
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$index->deleteByQuery($query);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Execute given callback with Elastica Type based on provided documentType
|
* Execute given callback with Elastica Type based on provided documentType
|
||||||
*
|
*
|
||||||
|
@ -202,7 +222,7 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
*/
|
*/
|
||||||
protected function withType(string $documentType, callable $callback)
|
protected function withType(string $documentType, callable $callback)
|
||||||
{
|
{
|
||||||
$type = $this->getType($documentType);
|
$type = $this->getType();
|
||||||
// TODO: Check whether it's to heavy to send it so often e.g. for every single document.
|
// TODO: Check whether it's to heavy to send it so often e.g. for every single document.
|
||||||
// Perhaps add command controller to submit mapping?!
|
// Perhaps add command controller to submit mapping?!
|
||||||
// Also it's not possible to change mapping without deleting index first.
|
// Also it's not possible to change mapping without deleting index first.
|
||||||
|
@ -230,17 +250,16 @@ class Elasticsearch implements Singleton, ConnectionInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $documentType
|
|
||||||
* @return \Elastica\Type
|
* @return \Elastica\Type
|
||||||
*/
|
*/
|
||||||
protected function getType(string $documentType): \Elastica\Type
|
protected function getType(): \Elastica\Type
|
||||||
{
|
{
|
||||||
return $this->typeFactory->getType(
|
return $this->typeFactory->getType(
|
||||||
$this->indexFactory->getIndex(
|
$this->indexFactory->getIndex(
|
||||||
$this->connection,
|
$this->connection,
|
||||||
$documentType
|
'document'
|
||||||
),
|
),
|
||||||
$documentType
|
'document'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,7 +60,6 @@ class DocumentFactory implements Singleton
|
||||||
}
|
}
|
||||||
|
|
||||||
$identifier = $document['search_identifier'];
|
$identifier = $document['search_identifier'];
|
||||||
unset($document['search_identifier']);
|
|
||||||
|
|
||||||
$this->logger->debug(
|
$this->logger->debug(
|
||||||
sprintf('Convert %s %u to document.', $documentType, $identifier),
|
sprintf('Convert %s %u to document.', $documentType, $identifier),
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Codappix\SearchCore\Domain\Index;
|
||||||
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
|
use Codappix\SearchCore\Configuration\ConfigurationContainerInterface;
|
||||||
use Codappix\SearchCore\Configuration\InvalidArgumentException;
|
use Codappix\SearchCore\Configuration\InvalidArgumentException;
|
||||||
use Codappix\SearchCore\Connection\ConnectionInterface;
|
use Codappix\SearchCore\Connection\ConnectionInterface;
|
||||||
|
use Elastica\Query;
|
||||||
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
use TYPO3\CMS\Core\Utility\GeneralUtility;
|
||||||
|
|
||||||
abstract class AbstractIndexer implements IndexerInterface
|
abstract class AbstractIndexer implements IndexerInterface
|
||||||
|
@ -130,7 +131,13 @@ abstract class AbstractIndexer implements IndexerInterface
|
||||||
public function delete()
|
public function delete()
|
||||||
{
|
{
|
||||||
$this->logger->info('Start deletion of index.');
|
$this->logger->info('Start deletion of index.');
|
||||||
$this->connection->deleteIndex($this->getDocumentName());
|
$this->connection->deleteIndexByQuery(Query::create([
|
||||||
|
'query' => [
|
||||||
|
'regexp' => [
|
||||||
|
'search_identifier' => $this->getDocumentName() . '-*'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]));
|
||||||
$this->logger->info('Finish deletion.');
|
$this->logger->info('Finish deletion.');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,10 +168,21 @@ abstract class AbstractIndexer implements IndexerInterface
|
||||||
} catch (InvalidArgumentException $e) {
|
} catch (InvalidArgumentException $e) {
|
||||||
// Nothing to do.
|
// Nothing to do.
|
||||||
}
|
}
|
||||||
|
$this->generateSearchIdentifier($record);
|
||||||
$this->handleAbstract($record);
|
$this->handleAbstract($record);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $record
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
protected function generateSearchIdentifier(array &$record)
|
||||||
|
{
|
||||||
|
if (!isset($record['search_identifier']) && isset($record['uid'])) {
|
||||||
|
$record['search_identifier'] = $this->getDocumentName() . '-' . $record['uid'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array $record
|
* @param array $record
|
||||||
* @return void
|
* @return void
|
||||||
|
|
|
@ -168,9 +168,6 @@ class TcaTableService implements TcaTableServiceInterface
|
||||||
*/
|
*/
|
||||||
public function prepareRecord(array &$record)
|
public function prepareRecord(array &$record)
|
||||||
{
|
{
|
||||||
if (isset($record['uid']) && !isset($record['search_identifier'])) {
|
|
||||||
$record['search_identifier'] = $record['uid'];
|
|
||||||
}
|
|
||||||
if (isset($record[$this->tca['ctrl']['label']]) && !isset($record['search_title'])) {
|
if (isset($record[$this->tca['ctrl']['label']]) && !isset($record['search_title'])) {
|
||||||
$record['search_title'] = $record[$this->tca['ctrl']['label']];
|
$record['search_title'] = $record[$this->tca['ctrl']['label']];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue