A zero-result page is the single worst outcome a search box can produce: the visitor typed something, meant something, and got nothing back. On most storefronts, 2–8% of searches return zero hits — and after a catalogue migration or a supplier feed change, that number can spike overnight.
Why queries fail
Zero hits almost never mean "the product doesn't exist." The most common causes are:
- Wrong keyboard layout. A visitor types
ghbdtnbecause their keyboard was switched to Cyrillic and they meantпривет. Same keys, wrong script. - Transliteration mismatches. A Russian-speaking shopper searches
kroksyforкроксы, or the reverse. - Homoglyphs. A Cyrillic
а(U+0430) looks identical to a Latina(U+0061) but is a different character to a search engine. - Genuine typos beyond what typo tolerance catches, especially on short queries where one wrong letter is a large fraction of the string.
Typo tolerance alone (num_typos, prefix/infix matching) handles the last case. It does nothing for the first three, because the query isn't misspelled — it's written in the wrong alphabet or script entirely.
The rescue ladder
When a search returns zero hits, AACSearch doesn't just show an empty state. It retries the query through a small, ordered set of rewrite strategies:
- Layout correction — remap the query as if it were typed on the other keyboard layout, and retry.
- Transliteration — convert Cyrillic ↔ Latin using the same tables a human would use mentally, and retry.
- Homoglyph normalization — fold visually identical characters from different scripts to one canonical form.
- Query broadening — drop the least selective token, then relax exact-match requirements, escalating only as far as needed to get a non-empty result.
Each step runs as an additional search against the engine (via multi_search, so it's one round trip, not four sequential ones), and the first strategy that returns hits wins. The response tells you which one fired — the response includes a query_rewrite.strategy field — so your UI can show "Showing results for кроксы" instead of silently substituting the query.
What this looks like from the API
A search for ghbdtn against a Russian catalogue returns the rewritten query metadata alongside the hits:
Nothing about this requires you to pre-guess which language or script a visitor will type in. The ladder tries cheap, structural rewrites first and stops as soon as one works, so the common case (a real typo the engine already tolerates) never pays for the extra round trips.
Measuring whether it's working
Fixing zero-result queries silently is only half the job — you also want to know your zero-result rate is actually dropping. The search quality lab tracks a zero-result rate metric per collection over time, and the query log records which rescue strategy fired for every search, so you can see exactly how much of your zero-result problem was a keyboard layout issue versus a genuinely missing product.
Try it
If your catalogue serves a mixed-script audience — Cyrillic and Latin, or any combination where transliteration is common — this ladder runs by default on every collection. No configuration required.
Похожие посты
Faceted search that scales to millions of SKUs
Why facet counts get slow as a catalogue grows, the difference between an exact and an estimated count, and how to keep faceted navigation fast without hiding filters shoppers need.
Webhook delivery: signatures, retries and safe replays
How AACSearch signs outbound webhooks, what happens when your endpoint is briefly down, and how an Idempotency-Key keeps a retried write from landing twice.
Multi-tenant search architecture: how tenant isolation works in AACSearch
Collection namespacing on the engine proxy, full versus search key scopes, short-lived browser keys, per-organization quotas in a Durable Object and organization-scoped events — what a platform operator gets when embedding search for many customers.