1

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);
}
1

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);
| improve this answer | |
  • This code works, but for some reason not when called from an install script (saving the store should already have triggered it anyways). As a workaround I added it in the first fixture instead that uses products, where the tests would have crashed without the tables. – Fabian Schmengler Apr 6 '17 at 12:15

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.