The search box is the highest purchase-intent path in any shop, and usually the worst maintained. People who type want to buy, not browse. Yet 56% of sites fail to adequately support their users' search needs (Baymard Institute). The culprit is rarely the search engine itself but its search relevance configuration: a multi-word query like "blue running shoes" returns either thousands of hits or none at all, German compound words fall apart uncontrollably, and product codes vanish between digit sequences. This guide shows how to tune the OpenSearch-based search of an online shop at the decisive levers: minimum_should_match, decompounding, synonyms, weighting of exact matches, special-character handling, autocomplete and variant search. And how to measure the effect instead of claiming it.

Why internal search is the most important path in the shop

Anyone using search has already put their need into words. That is a qualitatively different state from clicking through a category. Expectations of the result list are correspondingly high, and every miss is correspondingly expensive. In the user testing behind the 2026 Search UX benchmark, roughly half of participants preferred search as their product-finding strategy (Baymard Institute). The benchmark comprises more than 10,000 performance ratings across over 170 sites and apps (Baymard Institute), making it one of the broadest publicly documented data sets on the subject.

The results are sobering: 46% of desktop sites, 58% of mobile sites and 64% of apps achieve only mediocre or worse Search UX performance (Baymard Institute). It is also notable that search has long since stopped being used for products alone: 34% of test participants also searched for non-product content such as return policies (Baymard Institute). A search that only knows the product index runs dry on roughly a third of queries.

The breakdown by query type is even more instructive. It shows that search is not universally poor but fails at specific, clearly nameable classes of queries. Those classes are exactly what configuration can address.

Query typeShare with issuesExample
Exact search (product name)12%Nike Pegasus 41
Product type20%running shoes
Feature39%waterproof running shoes
Symptom37%heel pain
Use case43%shoes for a marathon
Compatibility44%replacement sole for model X
Abbreviation and symbol54%32/34, 1.5 l, XL
Non-product query66%returns, shipping costs

The pattern is unambiguous: the further a query moves away from the exact product name, the more often search fails. Exact searches have issues in only 12% of cases, abbreviation and symbol searches in 54% (Baymard Institute). The area with the largest losses is therefore also the one that a clean analyzer and relevance configuration improves most directly.

The lever at a glance

56% of sites fail to adequately support search needs, 64% of apps land in the mediocre-or-worse range for Search UX, and 54% of sites have issues with abbreviation and symbol searches (Baymard Institute). These are not design problems but predominantly configuration problems of the search engine.

minimum_should_match: how many terms have to match?

The single most consequential setting in multi-word search is minimum_should_match. The parameter specifies the minimum number of optional clauses a document must match to appear in the result list at all (OpenSearch Documentation). "Blue running shoes" produces three terms. With minimum_should_match set to 1, a single one suffices: every blue product and every shoe lands in the list. The result is the classic result flood in which the genuinely fitting articles drown.

The defaults are not intuitive. If a query contains a must or filter clause, the default is 0. If a Boolean query consists exclusively of should clauses, the default is 1, meaning at least one clause must match (OpenSearch Documentation). Configure nothing and you are effectively running your search on OR logic, which explains most result floods in practice.

OpenSearch accepts several value forms for the parameter, and their effects differ markedly:

Value formExampleMeaning
Non-negative integer2The document must match this number of optional clauses
Negative integer-1All optional clauses minus this number must match
Percentage70%This share of clauses, rounded down to the nearest integer
Negative percentage-30%This share of clauses may fail to match, rounded down
Combination2<75%Up to 2 terms all, above 2 terms 75% of the terms
Multiple combinations3<-1 5<50%Tiered rules depending on the number of terms

The rounding behaviour matters: percentages are rounded down to the nearest integer. If the calculation yields less than 1, then 1 is used; if it exceeds the number of optional clauses, it is capped at that number (OpenSearch Documentation). With three terms and 75% the maths gives 3 × 0.75 = 2.25, rounded down to 2. Two of the three terms in "blue running shoes" must therefore match: narrow enough to end the result flood, wide enough not to collapse to zero on a typo or an unusual attribute.

This is precisely why the combination form is the most practical starting value. An expression in n<p% format means: if the number of optional clauses is less than or equal to n, the document must match all optional clauses; if it is greater, it must match the p percentage (OpenSearch Documentation). 2<75% therefore demands completeness for one- and two-word queries and only loosens from three terms onward. That matches actual user behaviour: short queries are meant precisely, long ones often carry one attribute too many.

search-query.json
{
  "query": {
    "bool": {
      "should": [
        { "match": { "name": "blue" } },
        { "match": { "name": "running shoes" } },
        { "match": { "properties.name": "blue" } }
      ],
      "minimum_should_match": "2<75%"
    }
  }
}

Shopware brought this lever into the search configuration with 6.7. Since then merchants can configure how many terms in a search query need to match, so that multi-word queries are evaluated more intelligently. The vendor explicitly cites searches such as "blue running shoes", which return more relevant results while reducing overly broad matches (Shopware AG). Technically the search logic works with a strictness value on a scale from 0.0 to 1.0: 0.0 requires at least one term (OR), 1.0 all terms (AND), and values in between require ceil(numberOfTerms × strictness) matches (Shopware Developer Documentation). The interface offers five predefined strictness levels for this, replacing the earlier plain AND/OR toggle (Shopware AG).

Starting value and adjustment

In our experience a mid-range strictness value, or 2<75%, is a workable starting point for catalogues with well-maintained product names (project experience). Adjustment afterwards is not a matter of feel but of the zero-results rate and the search exit rate: if the zero-results rate rises noticeably after tightening, the step was too large.

German compound words break every naive search

German forms compound words, English does not. "Lederjacke" (leather jacket), "Fahrradschlauch" (bicycle tube) or "Edelstahlspüle" (stainless steel sink) are a single token, and a search for "Jacke" simply will not find "Lederjacke" without extra work. For shops with a German-language catalogue this is not a fringe topic but the most common cause of inexplicable zero results for products that are demonstrably in stock.

OpenSearch solves this with decompounder token filters, which are particularly useful for languages such as German, Dutch and Swedish in which compound words are common (OpenSearch Documentation). Two procedures are available, differing in speed and precision:

hyphenation_decompounder

Uses hyphenation patterns from an XML file to identify possible split points, then checks the components against a dictionary. The filter is faster than the dictionary decompounder and is the recommended filter for decompounding (OpenSearch Documentation).

dictionary_decompounder

Determines by brute force, without hyphenation rules, whether a token can be split into known words from a word_list, and generates the subtokens on a match (OpenSearch Documentation). More precisely controllable, but more compute-intensive.

Shopware relies on the dictionary variant in its advanced search configuration: since Commercial 7.12.0 a dictionary_decompounder splits compound nouns such as "Lederjacke" at index time using editable dictionaries (Shopware Developer Documentation). The decisive point is in the fine print: the filter applies only to the index analyzer, not to the search queries themselves (Shopware Developer Documentation). Miss that and you will look for the effect in the wrong place.

advanced_search.yaml
advanced_search:
    analysis:
        analyzer:
            sw_german_custom_analyzer:
                type: custom
                tokenizer: standard
                filter: ['lowercase', 'my_stopwords_filter', 'my_decompounder']
        filter:
            my_decompounder:
                type: dictionary_decompounder
                word_list: ['leder', 'jacke', 'fahrrad', 'schlauch']

The dictionaries are not maintained in YAML but as entities via the Admin API: advanced_search_compound_dictionary for root words and advanced_search_stopword_dictionary for custom stopwords (Shopware Developer Documentation). The analyzer is bound to the ISO language code via the language_analyzer_mapping parameter (Shopware Developer Documentation). After every dictionary change a bin/console es:index is due, otherwise the index stays on the old state (Shopware Developer Documentation).

In addition, Shopware aligned the handling of concatenated words with 6.7.12.1: concatenated and separated variants now count as equivalent, so a search for "jacket" also finds products containing compound terms such as "leather jacket" or "leatherjacket" (Shopware AG). It is also worth knowing that fields marked as searchable with the "Split search term" option enabled are handled by an n-gram tokenizer; the associated ses_ngram filter works with parameters of 3 as minimum and 27 as maximum (Shopware Developer Documentation).

Synonyms: what customers say, what the catalogue calls it

There is usually a gap between the language of the catalogue and the language of the customer. The catalogue knows "notebook", people search for "laptop". The catalogue lists "WLAN repeater", people type "wifi booster". Synonym lists close that gap, and they do it where they cause the least damage: at search time.

OpenSearch provides the synonym_graph token filter for this. It handles multi-word synonyms correctly by producing a token graph that preserves positions across terms of different lengths (OpenSearch Documentation). This is exactly what the older, simple synonym filter cannot do: with rules such as "w-lan, wlan, wireless network" it shifts positions and produces incorrect phrase matches. The expand parameter defaults to true (OpenSearch Documentation) and expands a rule in every direction.

The Shopware search configuration offers two rule types whose difference is often underestimated in practice (Shopware Developer Documentation):

  • Equivalence treats terms as completely interchangeable, for example wifi, wlan, w-lan. Every direction applies, every term finds the matches of all others. Suitable for genuine word equivalence.
  • Explicit mapping maps a search term directionally to different results, for example iPhone => smartphone. The assignment applies in one direction only. Suitable for brands, categories and colloquial short forms.
  • Language selection is optional for both types, and synonym rules are limited to 100 characters (Shopware Developer Documentation).

The most common mistake is reaching for equivalence where a mapping belongs. Storing iPhone and smartphone as equivalent turns every Android device into an iPhone match and produces exactly the result flood that minimum_should_match has just eliminated. Overly generous lists are equally risky: every synonym rule increases the number of optional clauses and thereby indirectly dilutes the effect of the minimum-match rule.

Derive synonyms from real search logs

Synonym lists should not be invented but derived from actual search queries. The candidates sit in the zero-result queries and in the sessions with a high refinement rate. The guide to site search analytics and search behaviour shows how to evaluate this data systematically.

Weighting exact matches above similar-looking results

Once the result set is narrowed, ordering decides. And here a classic of shop search shows itself: a product whose name matches the query exactly lands in position 7 while an article with a keyword-stuffed description sits on top. The cause is rarely malice but scoring.

Shopware sharpened several places with 6.7. Search applies improved relevance thresholds to reduce low-quality matches; weakly related results are filtered out so that customers are more likely to see products closely matching their search intent (Shopware AG). Keyword-heavy products also no longer receive an unfair ranking advantage simply because they contain large numbers of keywords: search places greater emphasis on the quality and relevance of matching keywords than on their quantity (Shopware AG). And the ranking logic prioritises exact matches more strongly over similar-looking results, while products matching across multiple attributes receive higher relevance scores (Shopware AG).

Technically the most relevant change concerns the dis_max queries: they now include a tie_breaker parameter at the field level, the translated field level and the token combination level. Previously dis_max considered only the single best-matching clause. With tie_breaker, scores from other matching clauses contribute partially to the overall score, improving ranking for documents that match across multiple fields or language variants (Shopware AG).

SituationWithout tie_breakerWith tie_breaker
Match in product name onlyScore from the name fieldScore from the name field
Match in name and descriptionOnly best field countsBest field plus others partially
Match across multiple language fieldsOnly best field countsLanguage variants support the score
Product matches one attribute broadlyCan outrank an exact name matchExact match stays in front

In addition, the ranking score per searchable field controls the weighting: the higher the value, the more weight the field brings to the result list (Shopware Developer Documentation). The rule of thumb is unspectacular but effective: product name and product number get the highest weight, category and manufacturer a medium one, the long description a low one. Weight the description too highly and the text wins regularly, not the product. If you are revising your product data anyway, automated product data enrichment provides the right foundation, because relevance can only be drawn from fields that are actually populated.

Handling product codes, sizes like 32/34 and units cleanly

This is where search loses the most revenue in practice, and where research confirms the finding most clearly: 54% of sites have issues with abbreviation and symbol searches (Baymard Institute). The reason usually lies with the tokenizer. By default Shopware allows only a defined set of special characters when tokenizing, in order to prevent indexing and search problems. The shopware.search.preserved_chars parameter defaults to ['-', '_', '+', '.', '@'] (Shopware Developer Documentation).

The forward slash is missing from that list. This is exactly what makes the clothing size 32/34 a problem case: it is split into 32 and 34 and therefore matches every pair of trousers carrying a 32 or a 34 anywhere. The same pattern hits product numbers. The documentation cites the number PT-64/515 as an example: if "Split search terms" is active, the search runs for PT, 64 and 515; if the option is inactive, PT-64/515 is preserved as a whole (Shopware Developer Documentation). To preserve slashes, override the parameter in your own config/packages/shopware.yaml (Shopware Developer Documentation).

config/packages/shopware.yaml
shopware:
    search:
        preserved_chars: ['-', '_', '+', '.', '@', '/', ',']
        term_max_length: 255

Decimal values and units behave analogously. "1.5 l" disintegrates into 1 and 5 without a preserved separator, and "0.5\" thread" into unusable fragments without a preserved period. Allow comma and period as separators and every measurement becomes unsearchable. Length matters too: the minimum length of a search term is 2 characters, the default is set to 3, and the maximum is 255 characters (Shopware Developer Documentation). With the default at 3, a search for XL or M is technically impossible, even though these rank among the most frequent queries in fashion shops.

How delicate this mechanism is becomes clear from a correction in 6.7.12.0: the n-gram subfield was removed from the text and textBoosted fields so that identifiers such as EANs and product numbers no longer inflate n-gram scoring. This fixed a regression in which a full GTIN search could be outranked by unrelated products with overlapping digit substrings (Shopware AG). That case is expensive in B2B: anyone typing a 13-digit GTIN expects exactly one hit.

Do not blindly open up all special characters

The temptation to simply preserve every special character is strong. That only inverts the problem: each additional preserved character produces longer, rarer tokens and therefore new zero results. The sensible approach is a selection along your own catalogue, that is / for clothing sizes, , for decimal values, . for inch specifications. After every change a full reindex is required, and the zero-results rate should be watched afterwards (project experience).

Configuring autocomplete and variant search

Autocomplete is where relevance becomes visible before any search has happened. The feature is present on roughly 80% of sites, yet only 19% implement all design patterns correctly (Baymard Institute). Volume is a frequent failure point: for desktop users the number of suggestions should not exceed 10, while 4 to 8 suggestions work for most mobile users (Baymard Institute).

Technically, autocomplete belongs on a dedicated field, not on the full-text index. Shopware took exactly this route with 6.7.12.0: admin search autocomplete uses a new, n-gram-indexed completion field populated with name-shaped values per entity (Shopware AG). The side effect is the real gain: because the n-gram subfield disappears from the text fields, identifiers and running text no longer compete in the same scoring.

Sequence is decisive during the switch. After deployment, bin/console es:admin:index must be executed to update the indices. Identifier searches do work immediately on older indices, but substring autocomplete operates only in a degraded prefix-only mode until the reindex completes (Shopware AG). A deployment without a subsequent reindex therefore looks like a feature bug.

For shops with variants a second addition matters. The parent.name search field allows variants to be found through their parent product name and ranked independently from the variant's own name. The field is disabled by default and has to be enabled in the product search configuration, where its ranking can also be adjusted (Shopware AG). The effect is considerable: if the parent product is called "Pegasus Trail" and the variant only "42 / Blue", the variant was previously all but unfindable via the product name.

  • Enable parent.name, but weight it lower than the variant's own name, otherwise variants push out the parent product
  • Put autocomplete on a dedicated completion field instead of the full-text index
  • Limit the suggestion count to a maximum of 10 (desktop) or 4 to 8 (mobile) (Baymard Institute)
  • Reindex fully after every field or analyzer change

Measure the effect instead of claiming it

Every relevance change is a hypothesis. Whether it holds is decided not by the gut feeling of those involved but by a handful of metrics collected before and after the change. Without that measurement, search tuning is a matter of taste, and taste cannot be offset against revenue.

Zero-results rate

Share of queries without a result. The central control variable when tightening minimum_should_match: it rises when the configuration was set too narrow.

Search exit rate

Share of sessions ending after a search. If it rises despite available matches, the problem is not the result count but the ordering.

Conversion after search

Conversion rate of search sessions compared to the shop average. The only metric that ultimately justifies the effort.

It is also worth watching the refinement rate, the share of sessions in which the query is reformulated. It is the most sensitive early indicator: someone who retypes found the first list unusable, even if it contained matches. And it is the best source of synonym candidates, because the reformulation usually contains exactly the word that appears in the catalogue.

Handling zero results deserves particular attention, because this is where shops systematically waste purchase intent: according to the Search UX benchmark, nearly 50% of sites fail to provide users with effective ways to recover from a search that yields no results (Baymard Institute). An earlier analysis puts the share of sites whose no-results page is a plain dead end at 68% (Baymard Institute). A no-results page is not a fault in itself; it becomes one when it offers no way back into the catalogue.

A search change without before-and-after measurement is not an optimisation but an opinion with a deployment.

XICTRON development team

The same principle applies to evaluation as with data-driven optimisation in the shop: one change per round, a defined observation period, and a fixed set of reference queries that runs before every deployment. This set of 30 to 50 real queries, mixed from product names, product codes, compound words and attribute searches, is the cheapest insurance against relevance regressions (project experience).

Relevance configuration in practice

Before configuring anything, the preliminary question needs answering: is a search index worth it? The vendor documentation puts it cautiously but clearly: once a project uses several thousand data sets, it is worth integrating OpenSearch (Shopware Developer Documentation). OpenSearch is licensed under Apache 2.0 and is supported by Shopware on equal terms; the connection uses the same configuration variables.

One detail is regularly overlooked and costs hours: the regular Shopware search configuration has no effect as soon as OpenSearch is active (Shopware Developer Documentation). Anyone adjusting weightings in the admin area and wondering about the absence of effects is looking in the wrong place; searchable fields and their weights are then controlled through the advanced search configuration.

Terminal
$ bin/console es:index
Building index for product ... done
$ bin/console dal:refresh:index --use-queue
Refreshing all indices via message queue
$ bin/console es:admin:index
$ bin/console es:create:alias

The relevant environment variables are OPENSEARCH_URL for the hosts, SHOPWARE_ES_ENABLED to activate search, SHOPWARE_ES_INDEXING_ENABLED for indexing and SHOPWARE_ES_INDEX_PREFIX for index naming; for admin search, ADMIN_OPENSEARCH_URL and SHOPWARE_ADMIN_ES_ENABLED are added (Shopware Developer Documentation). For troubleshooting, SHOPWARE_ES_THROW_EXCEPTION is helpful, because relevance problems otherwise appear silently as an empty result set.

The order of the working steps is decisive, because every analyzer change forces a reindex and therefore needs a time window:

  1. Evaluate search logs: export top queries, zero-result queries and queries with a high refinement rate. Without real data, every configuration is guesswork.
  2. Define reference queries: pin down 30 to 50 real queries as regression protection, including their expected top matches.
  3. Clarify tokenizer and special characters: align preserved_chars with the catalogue, check the minimum length, test product numbers and sizes.
  4. Set up decompounding: maintain dictionaries for the most common compound words in the assortment, then reindex.
  5. Adjust minimum_should_match: start with 2<75% or a mid-range strictness level and refine against the zero-results rate.
  6. Set weights and synonyms: distribute ranking scores per field, derive synonyms from zero-result queries instead of inventing them.
  7. Enable autocomplete and variants: configure the completion field and parent.name, limit the suggestion count.
  8. Measure and adjust: compare zero-results rate, search exit rate and conversion after search over a defined period.

This sequence is deliberately iterative. Search relevance is not a project with a sign-off date but a recurring task: every new collection, every assortment extension and every season creates new search terms and therefore new zero results. Set the configuration once and leave it alone, and the relevance gained is typically lost again within a few assortment cycles (project experience). In addition, filters and search interlock, and SEO-safe control of filter URLs co-determines whether refined result lists remain indexable at all.

Search relevance is a revenue lever, not a nice-to-have

Internal search combines the highest purchase intent in the shop with the lowest maintenance intensity. That is an unusual combination, and it explains why comparatively small interventions have a large effect here. Setting minimum_should_match to a workable value, splitting compound words, deriving synonyms from real logs, weighting exact matches cleanly and not shattering product codes on the tokenizer: these are configuration tasks, not new development. They do, however, require data, measurement and repetition.

Once relevance configuration is exhausted, the next layer begins. Where users search in meanings rather than terms, semantic product search with vector search complements the lexical foundation, and an AI-powered product search adds a further layer on top. Neither replaces a clean base configuration though; both presuppose it, since a hybrid stack on an incorrectly tokenised index inherits its faults. If you are working on price presentation in parallel, consider the legally compliant design of strikethrough prices as well, because result lists show prices, and what appears in the list has to satisfy price indication rules.

XICTRON tunes shop searches on the basis of real search logs. We evaluate your queries, zero results and abandonments, derive the relevance configuration from them and back the effect with before-and-after figures rather than assertions. As a Shopware agency we handle analyzers, weighting, synonyms and reindex strategy, and through our development services also the connection to your existing infrastructure. Get in touch via our contact form if your search produces more result flood than results.

Sources and studies

This article is based on data and documentation from: OpenSearch — Official Documentation (Query DSL, minimum_should_match, analyzers, decompounder token filters, synonym_graph), Shopware Developer Documentation (OpenSearch setup, product search and analyzer configuration, preserved_chars, language analyzers and dictionaries), Shopware AG (release news and release notes on the search improvements in 6.7.x, in particular 6.7.12.0 and 6.7.12.1) and Baymard Institute (2026 Search UX benchmark with more than 10,000 performance ratings across over 170 sites and apps, autocomplete and zero-results research). Supplementary assessments from our own project work are marked as (project experience). The figures cited may vary depending on the time of collection, version and catalogue structure.

There is no universally correct value, because it depends on catalogue structure and data quality. In our experience the combination form 2<75% is a workable starting value: up to two terms all must match, from three terms onward 75%, which for three terms rounds down to two matches (OpenSearch Documentation). In Shopware this corresponds to a middle option among the five strictness levels (Shopware AG). After that, adjustment is typically driven by the zero-results rate: if it rises noticeably, the setting was too strict.

Because "Lederjacke" is a single token in German. Without decompounding there is no reason for the search engine to recognise "Jacke" within it. The decompounder token filters in OpenSearch address this, with hyphenation_decompounder considered faster and recommended (OpenSearch Documentation). In Shopware, since Commercial 7.12.0 a dictionary_decompounder splits such nouns at index time using editable dictionaries, explicitly not on the search queries themselves (Shopware Developer Documentation). After dictionary changes a reindex is generally required.

Because the forward slash is not preserved by default. The shopware.search.preserved_chars parameter defaults to ['-', '_', '+', '.', '@'], and the slash is missing from it (Shopware Developer Documentation). The entry is therefore split into 32 and 34 and matches far more products than intended. To process sizes of this kind cleanly, add / in your own config/packages/shopware.yaml and reindex afterwards. Bear in mind that every additionally preserved character lengthens the tokens and can therefore create new zero results elsewhere.

This was a known scoring behaviour that Shopware addressed with 6.7: keyword-heavy products no longer receive an unfair ranking advantage purely through the quantity of keywords, because search weights the quality and relevance of matching keywords more strongly than their number (Shopware AG). The ranking logic additionally prioritises exact matches more strongly over similar-looking results (Shopware AG). Beyond that it usually helps to lower the ranking score of the long description and weight product name and product number higher (Shopware Developer Documentation).

One common reason is that the regular Shopware search configuration has no effect as soon as OpenSearch is active; searchable fields are then controlled through the advanced search configuration (Shopware Developer Documentation). The second common reason is a missing reindex: analyzer and dictionary changes only take effect after bin/console es:index, and admin search indices after bin/console es:admin:index (Shopware Developer Documentation / Shopware AG). Until the reindex has completed, substring autocomplete typically operates only in a degraded prefix-only mode.

Through three metrics in a before-and-after comparison: zero-results rate, search exit rate and conversion after search. The zero-results rate checks whether tightening minimum_should_match went too far; the search exit rate reveals ordering problems despite available matches; conversion after search justifies the effort commercially. It is generally advisable to roll out one change per round and to check a fixed set of reference queries before every deployment. The article on site search analytics describes the systematic evaluation in more detail.