Magento2 Fulltext Indexer using swap table
Wed, Dec 21, 2016Magento2 Fulltext Indexer using swap table
Indexing in Magento2 is much faster than Magento1, but for fulltext indexing, still have few seconds user can search nothing.
I’ve developed the fulltext indexer plugin using swap table. Just index fulltext to a temporary table first, after indexing finished, swap the temporary table to the working table.
1. Define the plugin class
<?php
namespace Your\ModuleName\Plugin\Indexer\CatalogSearch;
use Magento\Framework\Search\Request\DimensionFactory;
use Magento\Framework\Indexer\ScopeResolver\IndexScopeResolver;
use Magento\Framework\App\ResourceConnection;
class IndexerHandler {
private $dimensionFactory;
private $indexScopeResolver;
private $resource;
private $isFullReindex = false;
private $swapDimensions;
private $indexName = \Magento\CatalogSearch\Model\Indexer\Fulltext::INDEXER_ID;
private $getIndexNameClosure;
public function __construct(
DimensionFactory $dimensionFactory,
IndexScopeResolver $indexScopeResolver,
ResourceConnection $resource
) {
$this->dimensionFactory = $dimensionFactory;
$this->indexScopeResolver = $indexScopeResolver;
$this->resource = $resource;
}
/**
* {@inheritdoc}
*/
public function aroundCleanIndex($origin, $processor, $dimensions)
{
$this->isFullReindex = true;
$this->swapDimensions = [];
foreach($dimensions as $di) {
$this->swapDimensions[] = $this->dimensionFactory->create(['name' => 'swap', 'value' => $di->getValue()]);
}
$processor($this->swapDimensions);
}
public function aroundSaveIndex($origin,$processor, $dimensions, $documents)
{
$processor($this->isFullReindex ? $this->swapDimensions : $dimensions, $documents);
if ($this->isFullReindex) {
$swapTableName = $this->getTableName($this->swapDimensions);
$originTableName = $this->getTableName($dimensions);
$tmpTable = $originTableName . '_del';
$this->resource->getConnection()
->query(sprintf('DROP TABLE IF EXISTS %s;', $tmpTable));
$this->resource->getConnection()
->query(sprintf('CREATE TABLE IF NOT EXISTS %s(id int);', $originTableName));
$this->resource->getConnection()
->query(sprintf('RENAME TABLE %s TO %s, %s To %s;',
$originTableName,
$tmpTable,
$swapTableName,
$originTableName));
}
}
private function getTableName($dimensions) {
return $this->indexScopeResolver->resolve($this->indexName, $dimensions);
}
}
Add it to plugin settings “etc/di.xml”
<type name="Magento\CatalogSearch\Model\Indexer\IndexerHandler">
<plugin name="fulltext_table_swap"
type="Your\ModuleName\Plugin\Indexer\CatalogSearch\IndexerHandler"
sortOrder="1" />
</type>
All done!