Configuring Multilingual Search in Magento Shops
AI generated
_doc
_index
Magento · Multilingual Search · Elasticsearch · Analyzer
Configuring Multilingual Search
in Magento shops without mixing relevance

One store view per language is not enough to truly run clean multilingual search in Magento. Only store-view-based index naming combined with language-specific Elasticsearch analyzers prevents German compound words from being split incorrectly or English stemming rules from being applied to French text.

18 min read Store View Index · Language Analyzer · Stemmer · Locale Mapping Magento 2.4.x · Elasticsearch 8.x · OpenSearch 2.x

1. Why multilingual search is more than translation

Multilingual search is underestimated in many Magento projects because at first glance it looks like a pure translation problem: product names and descriptions get translated per store view, and search seemingly works automatically in every language. In reality, working multilingual search requires significantly more than translated content: every language has its own grammatical rules, its own word formation patterns, and its own stopword lists, all of which need to flow into the search index's analyzer configuration.

An English standard analyzer applied to German product descriptions does not recognize compound words like "Laufschuhe" as a combination of "Lauf" and "Schuhe," and therefore cannot deliver meaningful partial matches. Conversely, a German analyzer applied to French content leads to incorrect stemming results, because the word endings and inflection rules of both languages are fundamentally different. Multilingual search therefore requires every language to be treated technically as its own search context, not merely as its own text variant.

This article shows how to build multilingual search cleanly in Magento: from the store-view-based index structure through language-specific analyzers to the typical mistakes that lead to mixed or incorrect search results.

2. Store-view-based index naming

Magento creates a dedicated Elasticsearch index for every store view, typically following the pattern magento2_product_<store_id>_v<version> with an alias without a version suffix for production access. This separation is the technical prerequisite for multilingual search: every language gets its own, physically separate index, so different mapping configurations, in particular different analyzers, are possible per language without affecting each other.

This separation is necessary but not sufficient on its own. Without additional analyzer configuration, every store view index uses the same generic standard analyzer, regardless of the actual language of the content. That means: even with correctly separated indices per store view, multilingual search remains insufficient unless every index is additionally configured with the analyzer matching its respective language.


# List all product search indices to verify per-store-view separation
curl -s -X GET "https://localhost:9200/_cat/indices/magento2_product_*?v"

# Show which alias points to which physical index for store id 2 (e.g. French)
curl -s -X GET "https://localhost:9200/_alias/magento2_product_2"

3. Language-specific analyzers: stemmer, stopwords, normalization

Elasticsearch ships prebuilt, language-specific analyzers for a large number of languages, each with a matching stemmer, matching stopword list, and matching normalization rules. The german analyzer, for example, knows German inflection forms and reduces "Laufschuhe," "Laufschuh," and "Laufschuhen" to the same word stem, while the french analyzer brings its own rules for accents and French elisions. These analyzers are the foundation of any working multilingual search, because they ensure grammatical variants of a word are reliably matched to the same search hit.

The stemmer is just one of three central components. The language-specific stopword list filters out common filler words such as "and," "the," "for" in English or "und," "der," "die" in German, which would otherwise distort relevance scoring. Normalization handles language-specific spelling variants, for example umlauts in German or accent marks in French, so a search for "Muhle" also finds "Muehle" or "Mühle," depending on the chosen normalization strategy.


PUT /magento2_product_2_v1
{
  "settings": {
    "analysis": {
      "filter": {
        "german_stemmer": { "type": "stemmer", "language": "light_german" },
        "german_stop": { "type": "stop", "stopwords": "_german_" }
      },
      "analyzer": {
        "german_product_analyzer": {
          "type": "custom",
          "tokenizer": "standard",
          "filter": ["lowercase", "german_stop", "german_normalization", "german_stemmer"]
        }
      }
    }
  },
  "mappings": {
    "properties": {
      "name": { "type": "text", "analyzer": "german_product_analyzer" },
      "description": { "type": "text", "analyzer": "german_product_analyzer" }
    }
  }
}

4. Configuring locale-to-analyzer mapping in Magento

Magento already knows the locale of every store view via the general/locale/code configuration, for example de_DE, en_US, or fr_FR. For clean multilingual search, it pays off to systematically link this existing information to the matching Elasticsearch analyzer, instead of manually maintaining a separate mapping for every language. A practical approach is a mapping table that maps locale codes to analyzer names, consulted when building the index settings request.

This mapping can be implemented as a dedicated configuration class that determines the appropriate analyzer setting for the respective store view before every full reindex. The advantage of this approach: new store views with already supported languages need no manual analyzer configuration, because the mapping is automatically derived from the locale. Only for new, previously uncovered languages does the mapping table need to be extended once.


<?php
declare(strict_types=1);

namespace Mironsoft\SearchExtension\Model\Adapter;

/**
 * Maps a Magento store locale code to the matching Elasticsearch
 * language analyzer, used when building per-store index settings.
 */
class LocaleAnalyzerResolver
{
    /**
     * @var array<string, string>
     */
    private const LOCALE_TO_ANALYZER = [
        'de_DE' => 'german_product_analyzer',
        'de_AT' => 'german_product_analyzer',
        'en_US' => 'english_product_analyzer',
        'en_GB' => 'english_product_analyzer',
        'fr_FR' => 'french_product_analyzer',
    ];

    private const DEFAULT_ANALYZER = 'standard';

    /**
     * Resolves the analyzer name for a given Magento locale code.
     *
     * @param string $localeCode
     * @return string
     */
    public function resolve(string $localeCode): string
    {
        return self::LOCALE_TO_ANALYZER[$localeCode] ?? self::DEFAULT_ANALYZER;
    }
}

5. Avoiding cross-language relevance bleed

A subtle but common problem in multilingual search is what is known as cross-language relevance bleed: search terms from one language produce unexpected hits in another language's index because both use the same generic analyzer. Without language-specific separation, a German search request against the English store view index can technically work but delivers poor relevance, because English stemming rules are incorrectly applied to German inflection forms.

The reliable protection against cross-language bleed is the consistent combination of store-view-specific indices and store-view-specific analyzers, as described in the previous sections. In addition, the search request itself should never run across multiple language indices at once, unless this is explicitly intended, for example for a global cross-store search. An accidental query against a wildcard index pattern such as magento2_product_* instead of against the specific store view alias is a common, easily overlooked cause of cross-language bleed in practice.

Language Locale Elasticsearch Analyzer Notable Aspect
German de_DE german / light_german Compound words, umlaut normalization
English en_US english Comparatively simple stemming rules
French fr_FR french Elisions, accent normalization
Japanese ja_JP kuromoji (plugin) No spaces between words, dedicated tokenizer
Chinese zh_CN smartcn (plugin) Character-based instead of word-based tokenization

6. Special cases: compound words and CJK languages

German and similar languages with productive compound word formation present a special challenge for multilingual search. A compound word like "Fahrradhelm" (bicycle helmet) should ideally be searchable both as a whole and by its parts "Fahrrad" and "Helm," so a search for "Helm" also finds bicycle helmets. The german analyzer offers a solution with the decompound filter, which automatically splits compound words into meaningful sub-words based on a dictionary.

The challenge is even greater with CJK languages such as Chinese, Japanese, and Korean, which use no spaces between words. Elasticsearch's standard tokenizer, based on whitespace, does not work for these languages. Instead, specialized plugins such as kuromoji for Japanese or smartcn for Chinese are needed, performing language-specific word segmentation before meaningful multilingual search is even possible for these markets. These plugins need to be installed separately on the Elasticsearch cluster and are not part of the standard installation.

7. Managing synonyms per language

Synonym lists for multilingual search must be maintained strictly separately per language, because the same concepts form different word families in different languages. The German synonym pair "Kopfhoerer" and "Headset" has its own, not directly transferable equivalent in English with "headphones" and "headset." A shared, cross-language synonym list almost inevitably leads to incorrect or missing links in at least one of the involved languages.

Technically this is solved via separate synonym filters per analyzer, referencing language-specific synonym files. These files can either be maintained statically as part of the index settings or updated dynamically via Elasticsearch's synonym API without triggering a full reindex. For multilingual search with frequently changing synonyms, for example seasonal marketing terms, the dynamic variant is by far the more practical choice.

8. Testing multilingual search quality

Testing multilingual search requires language-specific test cases, not just a translated copy of the same test queries. A test set for the German store view should specifically cover compound words, umlaut variants, and typical German inflection forms, while a French test set should check accent variants and elisions. Only this way can language-specific regressions be detected that would go unnoticed with a purely translated test set.

A simple but effective test is comparing the hit count for semantically equivalent requests in different spelling variants, for example "Muehle" versus "Mühle" in German. If both variants return the same hit count, normalization is working correctly. If the numbers differ significantly, this points to a faulty or missing analyzer setting for that language.

9. Practical example: a DE/EN/FR shop with custom analyzers

A realistic example: a shop operates three store views for Germany, the US, and France. Without multilingual search configuration, all three use the same standard analyzer, which leads to particularly poor hit quality for compound words in the German store view. The solution combines three measures: first the already existing store-view-based index separation, second a matching language analyzer with a decompound filter for German per store view, and third language-specific synonym lists automatically assigned to the right index via the LocaleAnalyzerResolver.

After the switch, the effect is most visible in compound word searches: a search for "Helm" in the German store view now also finds "Fahrradhelm" and "Skihelm," while English and French search remain equally precise as before, because they use their own, independent analyzer configurations. This example shows that multilingual search is not a one-time setup but requires ongoing maintenance of language-specific analyzer and synonym configurations as new markets are added.

Mironsoft

Multilingual search and Elasticsearch analyzers for international shops

Want search that is equally precise in every language?

We configure language-specific analyzers, prevent cross-language relevance bleed, and build reliable test cases for every language of your international Magento shop.

Analyzer setup

Language-specific stemmer, stopwords and normalization per store view

CJK and edge cases

Kuromoji, smartcn and compound word splitting for difficult languages

Quality assurance

Language-specific test sets against cross-language regressions

10. Summary

Working multilingual search in Magento emerges from the interplay of two levels: the store-view-based index separation Magento already provides by default, and a deliberate language-specific analyzer configuration that needs to be set up on top. Without this second level, the separation remains ineffective, because all indices use the same generic analyzer and therefore process neither compound words nor language-specific inflection forms correctly.

Anyone planning multilingual search for more than two or three European languages should plan for special cases such as CJK languages and compound word formation early, maintain language-specific synonym lists separately, and continuously verify with language-specific test cases that no cross-language mixing occurs. This discipline prevents international expansion from quietly degrading search results in individual markets.

Multilingual search in Magento: the essentials at a glance

Store view index

Physically separate indices per store view are the prerequisite, but not sufficient alone.

Language analyzer

Stemmer, stopwords and normalization need to be configured correctly per language.

Cross-language bleed

Arises from shared analyzers or incorrect wildcard queries across multiple language indices.

Special cases

German compound words with the decompound filter, CJK languages with a dedicated tokenizer plugin.

11. FAQ: Multilingual Search in Magento

1Is one index per store view enough?
No, only the prerequisite. Language-specific analyzer configuration is additionally needed.
2What does a language analyzer do?
Combines matching stemmer, stopword list and normalization for that language.
3What is cross-language bleed?
Incorrect hits in another language index, usually from a shared analyzer or wildcard query.
4How are German compounds processed?
Via the decompound filter in the german analyzer, dictionary-based splitting into sub-words.
5Why no standard tokenizer for Japanese?
No spaces between words, specialized plugins like kuromoji are needed.
6Shared or separate synonyms?
Always separate per language, shared lists lead to incorrect links.
7How to derive the analyzer from locale?
Via a mapping class from general/locale/code to the analyzer name.
8How to test multilingual quality?
With language-specific test cases for compounds, inflection and spelling variants.
9Reindex needed after analyzer change?
Yes, always full, because analyzer settings cannot be changed afterward.
10Simplest test for normalization?
Compare hit counts for the same query with and without umlaut or accent.