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.
Table of Contents
- 1. Why multilingual search is more than translation
- 2. Store-view-based index naming
- 3. Language-specific analyzers: stemmer, stopwords, normalization
- 4. Configuring locale-to-analyzer mapping in Magento
- 5. Avoiding cross-language relevance bleed
- 6. Special cases: compound words and CJK languages
- 7. Managing synonyms per language
- 8. Testing multilingual search quality
- 9. Practical example: a DE/EN/FR shop with custom analyzers
- 10. Summary
- 11. FAQ
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.