PHP / Magento Dev Blog

  • Publikacje
  • O autorze
  • Kontakt

Elasticsearch w Magento 2 – indeksowanie, debugowanie zapytań, własny analyzer dla polskiego

by Henryk Tews / wtorek, 11 sierpnia 2020 / Opublikowano w Magento 2

Od Magento 2.4 Elasticsearch jest jedynym wspieranym silnikiem wyszukiwania – MySQL Search został usunięty. Dla wielu sklepów to po prostu „działa”, ale gdy klient zgłasza że „wyszukiwarka nie znajduje właściwych produktów”, zaczyna się prawdziwa praca. Pokazuję jak Magento indeksuje dane w ES, jak debugować zapytania i jak rozszerzyć indeks o własne pola.

Jak Magento indeksuje produkty w Elasticsearch

Magento tworzy w Elasticsearch osobny indeks dla każdego store view, w formacie magento2_product_1 (gdzie 1 to ID store view). Indeks zawiera dokumenty JSON z danymi produktów – atrybuty searchable, filterable i sortable trafiają do odpowiednich pól zgodnie z mappingiem.

Pełna reindeksacja:

# Reindeksacja samego katalogu produktów
bin/magento indexer:reindex catalog_product_fulltext

# Sprawdzenie stanu indeksera
bin/magento indexer:status

# Podgląd indeksu bezpośrednio w Elasticsearch
curl http://localhost:9200/_cat/indices?v

# Sprawdzenie mappingu indeksu Magento
curl http://localhost:9200/magento2_product_1/_mapping | python3 -m json.tool

Debugowanie zapytań – co Magento wysyła do ES?

Najprostszy sposób podejrzenia zapytań to włączenie logowania w Elasticsearch i obserwowanie slow query log. Ale szybciej działa bezpośrednie odpytanie ES tym samym zapytaniem co Magento:

<?php

// Własny plugin do logowania zapytań ES - przydatny przy debugowaniu
namespace Vendor\Module\Plugin;

use Magento\Elasticsearch\Model\Adapter\ElasticsearchAdapter;
use Psr\Log\LoggerInterface;

class ElasticsearchQueryLogger
{
    public function __construct(
        private LoggerInterface $logger
    ) {}

    public function beforeQuery(
        ElasticsearchAdapter $subject,
        array $query
    ): array {
        if (isset($_GET['debug_es'])) {
            $this->logger->debug('ES Query', ['query' => json_encode($query, JSON_PRETTY_PRINT)]);
        }

        return [$query];
    }
}

Zapytanie można też skopiować z logów i uruchomić bezpośrednio przez curl aby zobaczyć co Elasticsearch zwraca i jak scoruje dokumenty:

curl -X GET "localhost:9200/magento2_product_1/_search?explain=true" \
  -H 'Content-Type: application/json' \
  -d '{
    "query": {
      "bool": {
        "must": [
          {"match": {"name": {"query": "buty", "boost": 2}}}
        ],
        "filter": [
          {"term": {"status": 1}},
          {"term": {"visibility": [2, 3, 4]}}
        ]
      }
    }
  }'

Parametr explain=true zwraca szczegółowe wyjaśnienie jak ES obliczył score dla każdego dokumentu – nieocenione przy debugowaniu „dlaczego ten produkt jest wyżej niż tamten”.

Rozszerzenie indeksu o własne atrybuty

Magento indeksuje w ES atrybuty oznaczone jako Use in Search, Searchable lub Used for Sorting. Możesz też dodać własne dane przez plugin do buildera indeksu:

<?php

namespace Vendor\Module\Plugin;

use Magento\Elasticsearch\Model\Adapter\BatchDataMapper\ProductDataMapper;

class AddCustomDataToIndex
{
    public function afterMap(
        ProductDataMapper $subject,
        array $documents,
        array $documentData,
        int $storeId,
        array $context
    ): array {
        foreach ($documents as $productId => &$document) {
            // Dodaj własne pole do dokumentu ES
            // np. liczba sprzedanych sztuk z ostatnich 30 dni
            $document['sales_count_30d'] = $this->getSalesCount((int) $productId, 30);

            // Pole tekstowe do wyszukiwania po tagach
            $document['custom_tags'] = $this->getProductTags((int) $productId);
        }

        return $documents;
    }

    private function getSalesCount(int $productId, int $days): int
    {
        // logika pobierania danych sprzedaży
        return 0;
    }

    private function getProductTags(int $productId): string
    {
        // logika pobierania tagów
        return '';
    }
}

Rejestracja pluginu w di.xml:

<?xml version="1.0"?>
<config>
    <type name="Magento\Elasticsearch\Model\Adapter\BatchDataMapper\ProductDataMapper">
        <plugin name="vendor_module_add_custom_data"
                type="Vendor\Module\Plugin\AddCustomDataToIndex"/>
    </type>
</config>

Własny analyzer – lepsza obsługa języka polskiego

Domyślna konfiguracja Elasticsearch nie jest optymalna dla języka polskiego. Dodanie analyzera ze stemmerem i stopwordami poprawia jakość wyników:

<?php

namespace Vendor\Module\Plugin;

use Magento\Elasticsearch\Model\Adapter\Index\Builder;

class AddPolishAnalyzer
{
    public function afterBuild(Builder $subject, array $settings): array
    {
        $settings['analysis']['analyzer']['polish_analyzer'] = [
            'type'      => 'custom',
            'tokenizer' => 'standard',
            'filter'    => [
                'lowercase',
                'polish_stop',
                'polish_stem',
            ],
        ];

        $settings['analysis']['filter']['polish_stop'] = [
            'type'      => 'stop',
            'stopwords' => '_polish_',
        ];

        $settings['analysis']['filter']['polish_stem'] = [
            'type'     => 'stemmer',
            'language' => 'polish',
        ];

        return $settings;
    }
}

Po zmianie konfiguracji analyzera konieczna jest pełna reindeksacja – Elasticsearch nie zmienia mappingu istniejącego indeksu, Magento musi go odtworzyć od nowa.

Elasticsearch w DDEV – weryfikacja połączenia

# Sprawdzenie czy ES odpowiada wewnątrz DDEV
ddev exec curl -s http://elasticsearch:9200

# Konfiguracja Magento - połącz z ES w kontenerze
ddev exec bin/magento config:set catalog/search/engine elasticsearch7
ddev exec bin/magento config:set catalog/search/elasticsearch7_server_hostname elasticsearch
ddev exec bin/magento config:set catalog/search/elasticsearch7_server_port 9200

# Test połączenia przez Magento
ddev exec bin/magento config:show catalog/search

Podsumowanie

Elasticsearch w Magento 2 to nie czarna skrzynka – mapowanie indeksu, struktura zapytań i mechanizm scorowania są dostępne i modyfikowalne. Warto zainwestować czas w zrozumienie jak Magento buduje zapytania ES zanim zaczniesz pisać własne rozszerzenia. Parametr explain=true i bezpośrednie odpytywanie ES przez curl to najszybsza droga do zrozumienia „dlaczego wyszukiwarka zwraca złe wyniki”.

About Henryk Tews

Co możesz przeczytać następne

Service Contracts – Data Interfaces i Repository Pattern
OpenSearch 3.x vector search – embeddingi przez Ollama, k-NN, hybrid search
Własny indekser – mview.xml, flat table, full/partial reindeksacja, triggerowane przez cron
  • Publikacje
  • O autorze
  • Kontakt

© 2026 Created by

GÓRA
Zarządzaj zgodą
Aby zapewnić jak najlepsze wrażenia, korzystamy z technologii, takich jak pliki cookie, do przechowywania i/lub uzyskiwania dostępu do informacji o urządzeniu. Zgoda na te technologie pozwoli nam przetwarzać dane, takie jak zachowanie podczas przeglądania lub unikalne identyfikatory na tej stronie. Brak wyrażenia zgody lub wycofanie zgody może niekorzystnie wpłynąć na niektóre cechy i funkcje.
Funkcjonalne Zawsze aktywne
Przechowywanie lub dostęp do danych technicznych jest ściśle konieczny do uzasadnionego celu umożliwienia korzystania z konkretnej usługi wyraźnie żądanej przez subskrybenta lub użytkownika, lub wyłącznie w celu przeprowadzenia transmisji komunikatu przez sieć łączności elektronicznej.
Preferencje
Przechowywanie lub dostęp techniczny jest niezbędny do uzasadnionego celu przechowywania preferencji, o które nie prosi subskrybent lub użytkownik.
Statystyka
Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do celów statystycznych. Przechowywanie techniczne lub dostęp, który jest używany wyłącznie do anonimowych celów statystycznych. Bez wezwania do sądu, dobrowolnego podporządkowania się dostawcy usług internetowych lub dodatkowych zapisów od strony trzeciej, informacje przechowywane lub pobierane wyłącznie w tym celu zwykle nie mogą być wykorzystywane do identyfikacji użytkownika.
Marketing
Przechowywanie lub dostęp techniczny jest wymagany do tworzenia profili użytkowników w celu wysyłania reklam lub śledzenia użytkownika na stronie internetowej lub na kilku stronach internetowych w podobnych celach marketingowych.
  • Zarządzaj opcjami
  • Zarządzaj serwisami
  • Zarządzaj {vendor_count} dostawcami
  • Przeczytaj więcej o tych celach
Zobacz preferencje
  • {title}
  • {title}
  • {title}