Magento 2 ElasticSuite虚拟分类自定义索引器未随规则更新触发失效
ElasticSuite虚拟分类定时索引器未在规则更新时标记失效的解决方法
问题背景
为ElasticSuite虚拟分类开发Magento 2定时更新(Update by Schedule)索引器,但后台修改虚拟规则时,该索引器未被标记为失效,需补充配置与逻辑触发索引器失效。
解决方案
1. 补充Mview订阅虚拟规则表
ElasticSuite的虚拟规则存储在独立数据表中,当前mview.xml仅订阅了分类基础属性表,需添加虚拟规则表的订阅(表名以ElasticSuite实际使用为准,通常为catalog_category_entity_virtual_rule):
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Mview/etc/mview.xsd"> <view id="elasticsuite_virtual_categories" class="Vendor\Module\Model\Indexer" group="indexer"> <subscriptions> <!-- 原有分类属性表订阅 --> <table name="catalog_category_entity" entity_column="entity_id" /> <table name="catalog_category_entity_datetime" entity_column="entity_id" /> <table name="catalog_category_entity_decimal" entity_column="entity_id" /> <table name="catalog_category_entity_int" entity_column="entity_id" /> <table name="catalog_category_entity_text" entity_column="entity_id" /> <table name="catalog_category_entity_varchar" entity_column="entity_id" /> <!-- 添加虚拟规则表订阅 --> <table name="catalog_category_entity_virtual_rule" entity_column="category_id" /> </subscriptions> </view> </config>
2. 添加索引器依赖配置
在indexer.xml中配置与ElasticSuite核心分类索引器的依赖,确保规则更新时连锁触发当前索引器失效:
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Indexer/etc/indexer.xsd"> <indexer id="elasticsuite_virtual_categories" view_id="elasticsuite_virtual_categories" class="Vendor\Module\Model\Indexer"> <title translate="true">ElasticSuite Virtual Category Indexing</title> <description translate="true">Reindex ElasticSuite catalog Virtual categories.</description> <!-- 添加依赖,关联ElasticSuite核心分类索引器 --> <depends> <indexer id="elasticsuite_categories" /> </depends> </indexer> </config>
3. 监听虚拟规则保存事件
通过事件观察者,在虚拟规则保存后手动标记索引器失效:
3.1 配置events.xml
<?xml version="1.0" encoding="UTF-8"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd"> <!-- 监听ElasticSuite虚拟规则保存完成事件 --> <event name="elasticsuite_virtual_category_rule_save_after"> <observer name="mark_virtual_category_indexer_invalid" instance="Vendor\Module\Observer\MarkVirtualCategoryIndexerInvalid" /> </event> </config>
3.2 实现观察者类
<?php declare(strict_types=1); namespace Vendor\Module\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Indexer\IndexerRegistry; use Vendor\Module\Model\Indexer; class MarkVirtualCategoryIndexerInvalid implements ObserverInterface { public function __construct( protected IndexerRegistry $indexerRegistry ) {} public function execute(Observer $observer) { /** @var \External\VirtualCategory\Model\Rule $virtualRule */ $virtualRule = $observer->getEvent()->getData('rule'); $categoryId = $virtualRule->getCategoryId(); // 标记当前分类对应的索引器失效 $indexer = $this->indexerRegistry->get(Indexer::INDEXER_ID); $indexer->invalidateList([$categoryId]); } }
4. 完善索引器execute方法
当前execute仅打印日志,需实现虚拟规则更新后的索引逻辑,重新计算对应分类的虚拟产品关联:
public function execute($ids) { $this->logger->info('⚙️ Running Virtual Category Indexer - execute()'); $this->logger->info('Category IDs passed: ' . json_encode($ids)); foreach ($ids as $categoryId) { try { // 获取目标分类与虚拟规则 $category = $this->storeManager->getStore()->getCategory($categoryId); $virtualRule = $this->readHandler->execute($category); // 调用ElasticSuite索引操作重新计算产品关联 $this->indexOperation->reindexVirtualCategory($category, $virtualRule); // 或执行自定义索引逻辑 $this->fullAction->executeRow($categoryId); } catch (\Exception $e) { $this->logger->error('Failed to reindex virtual category ' . $categoryId . ': ' . $e->getMessage()); } } }
内容的提问来源于stack exchange,提问作者AICHOUCH MEHDI
相关产品推荐
相关产品推荐

