You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:21:01