ph2m / magento2-elasticsearch
为 Magento 2 搜索使用 Elasticsearch
1.1.4
2024-09-04 16:11 UTC
Requires
- php: ~8.0
README
安装
首先,安装 Magento 模块
composer require ph2m/magento2-elasticsearch
您需要安装 ElasticSearch 的 analysis-icu 插件。
您必须锁定 Elasticsearch 配置
php bin/magento config:set --lock catalog/search/elasticsearch7_server_hostname <elasticsearch_hostname>
php bin/magento config:set --lock catalog/search/elasticsearch7_server_port <elasticsearch_port>
php bin/magento config:set --lock catalog/search/elasticsearch7_index_prefix <elasticsearch_index_prefix>
php bin/magento config:set --lock catalog/search/elasticsearch7_enable_auth <elasticsearch_enable_auth>
php bin/magento config:set --lock catalog/search/elasticsearch7_username <elasticsearch_username>
php bin/magento config:set --lock catalog/search/elasticsearch7_password <elasticsearch_password>
将文件 es.php.sample
复制到您的 Magento pub
目录,并根据需要自定义它。
cp vendor/ph2m/magento2-elasticsearch/etc/es.php.sample pub/es.php
更新您的 Magento_Theme/templates/html/header.phtml
文件以包含搜索表单。
<?php echo $block->getChildHtml('ph2m.elasticsearch.search.form') ?>
您可以在您的主题中自定义模板文件 PH2M_Elasticsearch::search/form.phtml
。
安装后,重新索引。
php bin/magento indexer:reindex
添加新的搜索对象(品牌、博客文章等)
让我们假设您有一个模块 Vendor_Brand,并且您想将品牌添加到搜索中。
更新 di.xml
以添加字段映射器
<type name="Magento\Elasticsearch\Model\Adapter\FieldMapper\FieldMapperResolver"> <arguments> <argument name="fieldMappers" xsi:type="array"> <item name="brand" xsi:type="string">Vendor\Brand\Model\Adapter\FieldMapper\BrandFieldMapper</item> </argument> </arguments> </type>
创建字段映射器类
<?php declare(strict_types=1); namespace Vendor\Brand\Model\Adapter\FieldMapper; use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; class BrandFieldMapper implements FieldMapperInterface { public function getFieldName($attributeCode, $context = []) { return $attributeCode; } public function getAllAttributesTypes($context = []) { return [ 'name' => [ 'type' => 'text', 'fields' => [ 'keyword' => [ 'type' => 'keyword', ], ] ], 'url_key' => [ 'type' => 'text', ], ]; } }
在 etc/indexer.xml
中声明新的索引器
<?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="brandsearch_fulltext" view_id="brandsearch_fulltext" class="Vendor\Brand\Model\Indexer\Fulltext"> <title translate="true">Brand Search</title> <description translate="true">Rebuild Brand fulltext search index</description> </indexer> </config>
在 etc/mview.xml
中声明视图
<?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="brandsearch_fulltext" class="Vendor\Brand\Model\Indexer\Fulltext" group="indexer"> <subscriptions> <table name="brand" entity_column="brand_id"/> </subscriptions> </view> </config>
创建索引器类 Vendor\Brand\Model\Indexer\Fulltext
<?php declare(strict_types=1); namespace Vendor\Brand\Model\Indexer; use Magento\AdvancedSearch\Model\Client\ClientResolver; use Magento\Elasticsearch\Model\Adapter\Elasticsearch; use Magento\Elasticsearch\Model\Adapter\Index\IndexNameResolver; use Magento\Framework\Api\SearchCriteriaBuilder; use Vendor\Brand\Api\Data\BrandInterface; use Vendor\Brand\Query\Brand\GetListQuery; use Psr\Log\LoggerInterface; class Fulltext implements \Magento\Framework\Indexer\ActionInterface, \Magento\Framework\Mview\ActionInterface { public function __construct( protected ClientResolver $clientResolver, protected GetListQuery $getListQuery, protected SearchCriteriaBuilder $searchCriteriaBuilder, protected Elasticsearch $elasticsearchAdapter, protected LoggerInterface $logger, protected IndexNameResolver $indexNameResolver ) { } public function execute($ids) { $this->executeList($ids); } public function executeFull(): void { $this->elasticsearchAdapter->cleanIndex(1, 'brand'); $this->executeList([]); $this->elasticsearchAdapter->updateAlias(1, 'brand'); } public function executeList(array $ids): void { $searchCriteria = $this->searchCriteriaBuilder; if (!empty($ids)) { $searchCriteria->addFilter(BrandInterface::BRAND_ID, $ids, 'in'); } $brands = $this->getListQuery->execute($searchCriteria->create())->getItems(); $brandsToReindex = []; foreach ($brands as $brand) { $brandsToReindex[] = [ 'name' => $brand->getName(), 'url_key' => $brand->getUrlKey(), ]; } try { $this->elasticsearchAdapter->addDocs($brandsToReindex, 1, 'brand'); } catch (\Throwable $e) { $this->logger->error($e->getMessage()); } } public function executeRow($id) { $this->executeList([$id]); } }
在 etc/events.xml
中添加 save_after
观察者
<event name="brand_model_save_after"> <observer name="brand_model_save_after" instance="Vendor\Brand\Observer\SaveAfter" /> </event>
以及相应的类
<?php declare(strict_types=1); namespace Vendor\Brand\Observer; use Magento\Framework\Event\Observer; use Magento\Framework\Event\ObserverInterface; use Magento\Framework\Indexer\StateInterface; use Magento\Indexer\Model\IndexerFactory; class SaveAfter implements ObserverInterface { public function __construct( protected IndexerFactory $indexerFactory, protected \Vendor\Brand\Model\Indexer\Fulltext $fulltextIndexer ) { } public function execute(Observer $observer): void { $index = $this->indexerFactory->create()->load('brandsearch_fulltext'); if ($index->isScheduled()) { $index->invalidate(); } else { $this->fulltextIndexer->executeRow($observer->getData('object')->getBrandId()); $state = $index->getState(); $state->setStatus(StateInterface::STATUS_VALID); $state->save(); $index->setState($state); } } }
同义词配置
您可以在“商店 > 配置 > 目录 > 目录 > 目录搜索 > 搜索同义词”中添加一些同义词。同义词必须由逗号分隔,每行一个同义词组。
Hyvä ready
此模块专为 Hyvä 设计。