TinyStore

Search / Typos

Typos

A word that matches nothing in the index is read as the nearest word the index holds, and corrected says what the search read in fact, so the page can show "Showing results for running shoes".

const { hits, corrected } = await products.search({ text: 'runing shoos' })
corrected // 'running shoes'
result = await products.search("runing shoos")
result.corrected  # 'running shoes'
result, err := products.Search(ctx, "runing shoos")
result.Corrected // "running shoes"
let found = products.search("runing shoos").run()?;
found.corrected // Some("running shoes")

corrected is absent ("" in Go) when the search read its words as given.

The rules

A word ofIs read with
up to 4 lettersno change: cat is never car
5 to 8 lettersone edit
9 letters or moretwo edits

An edit is a letter added, dropped or changed, or two neighbours swapped: shose is one edit from shoes.

  • A word that matches something is never changed (contract SRCH-09). bots finds documents with bots, even when boots is far more common.
  • Each word is corrected on its own: runing shoes keeps shoes and reads running.
  • A word is near only words of its own script: a Latin typo is never read as a Cyrillic word.
  • A search's words are any, not all: a document with one of them is a hit, ranked below those with more.

Turn it off

For codes, ids and names where a near word is a wrong word, an SKU or a ticket number, open the index without it:

const parts = store.index<Part>('parts', { fields: ['sku', 'name'], typoTolerance: false })
parts = store.index("parts", Part, fields=["sku", "name"], typo_tolerance=False)
parts, err := search.OpenIndex[Part](store, "parts", search.FieldNames("sku", "name"), search.TypoTolerance(false))
let parts = store.index::<Part>("parts").fields(["sku", "name"]).typo_tolerance(false).open()?;

Turning it on or off applies at once: nothing in the index is written again.

Where the words come from

The index keeps a dictionary of its own words, one per script, built the first time a search needs it. After writes, searches go on with the dictionary they have, reading no word their snapshot no longer holds, and background work builds it again within a minute. A word added a few seconds ago is found exactly at once, and as a correction a minute later.

Why this design?

Why only when a word matches nothing. A search engine that corrects words that exist second-guesses the user: a search for a rare brand turns into a search for a common word. Correcting only what matches nothing never loses a hit the user typed for.

Why five and nine letters. Short words sit one edit from many others: cat, car, cut, cot. Correcting them reads noise. The thresholds are the ones Meilisearch uses, so a search box behaves as people already expect.

Why say corrected. A search that silently searches for something else leaves the user wondering why the hits do not hold their word. Saying what was searched lets the page say so, and offer the original.

See also

Edit this page on GitHub Updated 19 October 2026

esc
↑↓ navigate ↵ open ⇥ filter 0 results