Question

Magento 2 creates one fulltext search table per store view, but I am wondering where exactly these are created and how I can force it.

Context: We have a setup script (InstallData) that creates store views, but in integration tests the fulltext tables for these store views are missing, which leads to errors from fixtures that try to save a product.

I tried reindexing in the setup script, after the stores were saved, but it did not help:

    ...

    $this->getIndexer('catalogsearch_fulltext')->reindexAll();
}

private function getIndexer($indexerId)
{
    return $this->indexerFactory->create()->load($indexerId);
}
Was it helpful?

Solution

It seems that it happens in the following observer -

Magento\CatalogSearch\Model\Indexer\Fulltext\Store

(on store_add event which seems to be fired when you save a new store view).

You can see that the observer eventually gets to Magento\CatalogSearch\Model\Indexer\IndexerHandler::cleanIndex, where it eventually calls \Magento\CatalogSearch\Model\Indexer\IndexStructure::delete and \Magento\CatalogSearch\Model\Indexer\IndexStructure::create, where it eventually gets to the following code that creates the catalogsearch_fulltext_scopeN table -

(class Magento\CatalogSearch\Model\Indexer\IndexStructure)

protected function createFulltextIndex($tableName)
{
    $table = $this->resource->getConnection()->newTable($tableName)
        ->addColumn(
            'entity_id',
            Table::TYPE_INTEGER,
            10,
            ['unsigned' => true, 'nullable' => false],
            'Entity ID'
        )->addColumn(
            'attribute_id',
            Table::TYPE_INTEGER,
            10,
            ['unsigned' => true, 'nullable' => false]
        )->addColumn(
            'data_index',
            Table::TYPE_TEXT,
            '4g',
            ['nullable' => true],
            'Data index'
        )->addIndex(
            'idx_primary',
            ['entity_id', 'attribute_id'],
            ['type' => AdapterInterface::INDEX_TYPE_PRIMARY]
        )->addIndex(
            'FTI_FULLTEXT_DATA_INDEX',
            ['data_index'],
            ['type' => AdapterInterface::INDEX_TYPE_FULLTEXT]
        );
    $this->resource->getConnection()->createTable($table);
}

(where $tableName is catalogsearch_fulltext_scopeN)

Therefore, in order to force the table creation, I suggest to run the following code in your setup script (it's an imitation of Magento\CatalogSearch\Model\Indexer\Fulltext\Store::clearIndex)

$indexerHandlerFactory = \Magento\Framework\App\ObjectManager::getInstance()->get("Magento\\CatalogSearch\\Model\\Indexer\\IndexerHandlerFactory");
$indexerConfig = \Magento\Framework\App\ObjectManager::getInstance()->get("Magento\\Framework\\Indexer\\ConfigInterface");
$dimensionFactory = \Magento\Framework\App\ObjectManager::getInstance()->get("Magento\\Framework\\Search\\Request\\DimensionFactory");

$dimensions = [
            $dimensionFactory->create(['name' => 'scope', 'value' => '<YOUR_STORE_VIEW_ID>'])
        ];
$configData = $indexerConfig->getIndexer('catalogsearch_fulltext');
$indexHandler = $indexerHandlerFactory->create(['data' => $configData]);
$indexHandler->cleanIndex($dimensions);
Licensed under: CC-BY-SA with attribution
Not affiliated with magento.stackexchange
scroll top