Home· Features· Synonyms & Typo Tolerance
🔁 Synonyms & Typo Tolerance

Two synonym shapes. Three typo dials.

Multi-way equivalence or one-way expansion, push-to-engine on save. Per-index typo budget, prefix matching, configurable stop-words, Romanian-aware morphology — all wired through the same search params.

Starter Growth Scale Enterprise
// Two synonym shapes, same table
{
  "type": "multi_way",        // symmetric
  "synonyms": ["phone", "smartphone", "mobile"],
  "enabled": true
}

{
  "type": "one_way",          // expansion
  "root":     "trainers",
  "synonyms": ["sneakers", "runners"],
  "enabled": true
}
Synonyms · two shapes

Pick equivalence or expansion. No other knobs.

Skryx stores synonyms in one table with a type column. Either they're symmetric (multi_way) or one-directional (one_way). Every create / update / delete idempotently re-pushes the full enabled-synonym list to the engine — DB and engine stay in lockstep, with no drift.

multi_way

Symmetric · true equivalence

All terms map to each other. ["phone", "smartphone", "mobile"] means a search for any of the three retrieves products tagged with any of the three. root is null.

one_way

Expansion · directional

root expands to synonyms[], but not vice versa. Searches for "trainers" also retrieve "sneakers" and "runners"; searches for "sneakers" don't pull in "trainers". Good for typo aliases and regional terms.

AI-suggested synonyms

Catalog-validated. Not LLM-hallucinated.

Two separate flows feed Skryx's synonym table from analytics. Both surface in AI Coach as one-click recommendations. Both verify the suggestion against your actual catalog before showing it.

🔁 Morphology pairs (Romanian today)

Singular ⇄ plural from real index tokens.

GenerateCatalogSynonymsJob walks your index, extracts title tokens that appear ≥ 2× and are ≥ 4 chars long, drops stopwords, and runs each through the Romanian morphology service to detect form and generate the opposite. A pair only survives if both forms appear in your top 2,000 frequent words.

  • 171 hand-curated irregular plurals + regular suffix rules
  • Confidence ≥ 0.85 required to surface
  • Up to 100 pairs in one Coach card, applied per-pair via checkboxes
  • Romanian today; English and other languages on the roadmap
// Coach: 89 morphology pairs
cască ⇄ căști 412×
adaptor ⇄ adaptoare 208×
baterie ⇄ baterii 183×
încărcător ⇄ încărcătoare 141×
[Apply selected] [Dismiss rest]
🔍 Missing-synonym suggestions

Skryx AI reads zero-result queries.

AI Coach (separate flow) looks at zero-result and low-CTR queries against your catalog sample and asks Skryx AI for synonym pairs to fix the gap. Output is post-filtered against your enabled synonyms and normalised for diacritics so already-applied pairs never come back.

  • Conservative prompt: "only suggest if the catalog clearly has the target"
  • 30-day cooldown on dismissed terms
  • One-click apply creates a multi_way row and syncs to engine
{
  "type": "missing_synonym",
  "confidence": "high",
  "search_count": 24,
  "payload": {
    "root": "trainers",
    "synonyms": ["sneakers", "runners"],
    "reason": "0 hits · catalog has 142 sneaker SKUs"
  }
}
Typo tolerance

Three dials. Per index. Per query.

Stored as a JSON config on the index. Sensible defaults shipped out of the box; tenants override per index in the Search Settings UI, or per query via num_typos in the request body.

⌨️ Per-index defaults

2 typos. Length floors that prevent nonsense.

Defaults: num_typos = 2, min_word_length_for_1_typo = 4, min_word_length_for_2_typos = 7. Short tokens (1–3 chars) get zero tolerance — a typo on "ipad" should not return "iped" — and the full 2-typo budget only unlocks on long words where it's actually safe.

  • Configured in indexes.typo_config JSON
  • Per-query override via the num_typos request param
  • Engine-side: budget applies uniformly across searchable fields
{
  "num_typos": 2,
  "min_word_length_for_1_typo": 4,
  "min_word_length_for_2_typos": 7
}

// Behaviour:
"ip"      → 0 typos allowed
"iphn"    → 1 typo allowed  (4 chars)
"iphone"  → 1 typo allowed  (6 chars)
"iphonr5" → 2 typos allowed (7 chars)
⚡ Prefix matching

On by default. Disable per query if you need to.

Skryx passes prefix=true on every query unless the caller explicitly sets prefix=false. Critical for instant-search-as-you-type UIs where the customer hasn't finished typing yet.

  • Default: true for every query
  • Per-query override via the prefix request param
  • Combines with typo tolerance — "iphn" + prefix matches "iPhone"
"i" → too short, waits
"ip" → iPhone, iPad, iPod
"iph" → iPhone (all models)
"iphn" → iPhone (typo + prefix)
"iphn 15"→ iPhone 15
✂️ Stop-words

Strip the noise before it hits the engine.

Per-index stop_words JSON array. Skryx removes any word in the list from the query before sending it to the engine — no weight wasted on connectives like "the", "and", "for" when they don't carry intent.

  • Configured per index, edited from Search Settings
  • Romanian Coach prompts seed a working list of e-commerce noise (units, sizes, dimensions)
  • Bypassable per query: pass the raw query and Skryx still strips the configured words
{
  "stop_words": [
    "the", "a", "an",
    "for", "with", "in",
    "kg", "mm", "cm"
  ]
}

// "headphones for the office" →
// engine sees: "headphones office"
Transparency to the customer

"Showing results for X" when AI rewrote the query.

Synonym and typo expansion happen inside the engine — they don't surface separately in the API response. AI-driven query rewrites (from the Query Understanding step) do come back to your UI: the response includes ai_context.original_query, ai_context.rewritten_query, and a list of suggestions for "Did you mean?" banners.

{
  "hits": [ /* … */ ],
  "found": 142,
  "search_mode": "hybrid",
  "ai_enhanced": true,
  "ai_context": {
    "original_query":  "laptop for vid edting",
    "rewritten_query": "laptop for video editing",
    "intent":          "compare",
    "alternative_queries": [
      "4k editing laptop",
      "creator laptop"
    ]
  },
  "suggestions": ["video editing laptops"]
}

Render exactly what the customer expects.

Use original_query vs rewritten_query to render "Showing results for laptop for video editing" when they differ. Use suggestions[] for the "Did you mean?" row. Use ai_context.intent if you want to render different UI for purchase-intent vs problem-intent queries.

  • Always present, even when no rewrite happened (both fields equal)
  • ai_enhanced: false flag tells the UI to skip the banner
  • Same payload shape for keyword / semantic / hybrid modes
Operational details

No quotas. No surprises.

All plans
Synonyms + typo tolerance · no plan gating, no per-feature quota
~100 ms
Sync to engine after create / update / delete · idempotent re-push
0 ms
Added query-time latency · expansion happens engine-side at p99
Keep exploring

Other things Skryx does

Try it on your own catalog.

Free tier, no credit card. EU-hosted from day one.