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

如何在Magento 2中实现免费的搜索栏拼写纠错功能?

Hey John, great question—dealing with misspelled searches from less tech-savvy customers is such a common pain point, and since you can’t use third-party extensions, building this directly into Magento 2 via custom code is the perfect approach. Let’s walk through how to implement this step by step, using the method you referenced:

1. Core Concept: Fuzzy Matching & Spell Suggestions

We’ll modify Magento’s native search logic to add spell checking. The core idea is to compare the user’s misspelled query against your product catalog (names, SKUs, etc.) using a similarity algorithm (like Levenshtein Distance) to find the closest matching valid term, then surface that as a suggestion or auto-redirect to the correct results.

2. Implement via Custom Module (No Core Code Edits!)

Always use a custom module instead of modifying core files—it keeps your changes upgrade-safe. Here’s how to build it:

Step 1: Set Up the Custom Module Structure

Create a new module in app/code/YourVendor/SpellCorrection (replace YourVendor with your actual vendor name):

  • registration.php:

    <?php
    \Magento\Framework\Component\ComponentRegistrar::register(
        \Magento\Framework\Component\ComponentRegistrar::MODULE,
        'YourVendor_SpellCorrection',
        __DIR__
    );
    
  • etc/module.xml:

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
        <module name="YourVendor_SpellCorrection" setup_version="1.0.0">
            <sequence>
                <module name="Magento_CatalogSearch"/>
                <module name="Magento_Search"/>
            </sequence>
        </module>
    </config>
    

Step 2: Override the Search Query Model

We’ll override Magento’s native Query model to add our spell-checking logic.

  • etc/di.xml:

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <preference for="Magento\Search\Model\Query" type="YourVendor\SpellCorrection\Model\Query"/>
    </config>
    
  • Model/Query.php:
    This is where the magic happens—we’ll add a method to find the closest matching product term using Levenshtein Distance:

    <?php
    namespace YourVendor\SpellCorrection\Model;
    
    use Magento\Search\Model\Query as OriginalQuery;
    use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory;
    use Magento\Framework\App\ResourceConnection;
    
    class Query extends OriginalQuery
    {
        protected $productCollectionFactory;
        protected $resourceConnection;
    
        public function __construct(
            \Magento\Framework\Model\Context $context,
            \Magento\Framework\Registry $registry,
            \Magento\Search\Model\ResourceModel\Query $resource,
            \Magento\Search\Model\ResourceModel\Query\Collection $resourceCollection,
            \Magento\Search\Model\QueryFactory $queryFactory,
            \Magento\Framework\Session\SessionManagerInterface $session,
            \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
            \Magento\Framework\Stdlib\DateTime\DateTime $dateTime,
            CollectionFactory $productCollectionFactory,
            ResourceConnection $resourceConnection,
            array $data = []
        ) {
            $this->productCollectionFactory = $productCollectionFactory;
            $this->resourceConnection = $resourceConnection;
            parent::__construct(
                $context,
                $registry,
                $resource,
                $resourceCollection,
                $queryFactory,
                $session,
                $scopeConfig,
                $dateTime,
                $data
            );
        }
    
        public function getSuggestedQuery()
        {
            $originalQuery = $this->getQueryText();
            if (empty($originalQuery)) {
                return parent::getSuggestedQuery();
            }
    
            // Find the closest matching term from our product catalog
            $suggestedQuery = $this->findClosestMatchingTerm($originalQuery);
    
            if ($suggestedQuery && $suggestedQuery !== $originalQuery) {
                return $suggestedQuery;
            }
    
            // Fall back to Magento's native suggestion if no match is found
            return parent::getSuggestedQuery();
        }
    
        protected function findClosestMatchingTerm($searchTerm)
        {
            $connection = $this->resourceConnection->getConnection();
            $productTableName = $connection->getTableName('catalog_product_entity_varchar');
            $nameAttributeId = $this->getAttributeId('name');
    
            // Fetch all product names from the database
            $select = $connection->select()
                ->from($productTableName, ['value'])
                ->where('attribute_id = ?', $nameAttributeId)
                ->where('value IS NOT NULL');
    
            $productNames = $connection->fetchCol($select);
    
            $closestTerm = null;
            $minDistance = PHP_INT_MAX;
            // Ignore very short search terms to avoid false matches
            $minSearchLength = 3;
    
            if (strlen($searchTerm) < $minSearchLength) {
                return null;
            }
    
            foreach ($productNames as $name) {
                if (strlen($name) < $minSearchLength) {
                    continue;
                }
                // Calculate similarity between search term and product name
                $distance = levenshtein(strtolower($searchTerm), strtolower($name));
                // Adjust these thresholds based on your users' typical spelling errors
                if ($distance < $minDistance && $distance <= 2 && abs(strlen($name) - strlen($searchTerm)) <= 3) {
                    $minDistance = $distance;
                    $closestTerm = $name;
                }
            }
    
            return $closestTerm;
        }
    
        protected function getAttributeId($attributeCode)
        {
            $connection = $this->resourceConnection->getConnection();
            $eavAttributeTable = $connection->getTableName('eav_attribute');
            $select = $connection->select()
                ->from($eavAttributeTable, ['attribute_id'])
                ->where('entity_type_id = ?', 4) // 4 is the entity ID for products
                ->where('attribute_code = ?', $attributeCode);
    
            return $connection->fetchOne($select);
        }
    }
    
3. Display the Spell Suggestion to Users

Now we need to show the "Did you mean?" message on the search results page or mini search bar.

Edit your theme’s search template (e.g., app/design/frontend/YourTheme/Magento_Search/templates/result.phtml or form.mini.phtml) and add this code:

<?php $query = $block->getQuery(); ?>
<?php if ($suggestedQuery = $query->getSuggestedQuery()): ?>
    <div class="search-spell-suggestion">
        <?= __('Did you mean:') ?> <a href="<?= $block->getSearchUrl($suggestedQuery) ?>"><?= $suggestedQuery ?></a>
    </div>
<?php endif; ?>
4. Optimize for Performance
  • Add Full-Text Indexing: For large catalogs, add a FULLTEXT index to the product name column in MySQL to speed up similarity checks.
  • Cache Suggestions: Store computed search term suggestions in Magento’s cache to avoid repeating database queries.
  • Expand to More Fields: Modify the findClosestMatchingTerm method to include SKUs, descriptions, or other product attributes.
Final Setup Steps

Enable the module and compile the code:

bin/magento module:enable YourVendor_SpellCorrection
bin/magento setup:upgrade
bin/magento setup:di:compile
bin/magento cache:clean

内容的提问来源于stack exchange,提问作者John

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 03:25:01