Table of contents :

Handling Typo-Tolerant Product Search

100-days-of-elasticsearch-woocommerce-026

Table of contents :

Customers do not always enter product names exactly as they appear in the catalog. A shopper may search for wireles headphones, iphon case, or stainles steel bottle and still expect relevant products. Typo-tolerant search uses Elasticsearch’s fuzzy matching to recover from small spelling errors without requiring a perfect query.

How fuzzy matching works

Elasticsearch fuzzy matching compares terms using edit distance. An edit can be an insertion, deletion, substitution, or transposition. For example, headphons can match headphones because only a small number of edits are required.

The fuzziness option controls the permitted edit distance. A practical starting point is AUTO, which selects a distance based on the length of the term. For more predictable behavior, an agency may use an explicit value such as 1 for short product terms and 2 for longer terms.

A baseline WooCommerce product query

The following query searches product names, descriptions, and SKU-like identifiers while allowing limited spelling errors. The product name receives the highest boost, and exact SKU matches are handled separately.

{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "wireles headphones",
            "fields": [
              "name^5",
              "short_description^2",
              "description",
              "sku^3"
            ],
            "type": "best_fields",
            "fuzziness": "AUTO",
            "prefix_length": 1,
            "max_expansions": 50
          }
        },
        {
          "term": {
            "sku.keyword": {
              "value": "wireles headphones",
              "boost": 10
            }
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

prefix_length protects the beginning of a term from fuzzy expansion. This reduces noisy matches and limits query cost. max_expansions places an upper bound on the number of candidate terms Elasticsearch considers for each fuzzy term.

Use fuzziness selectively

Fuzzy matching should not be applied indiscriminately to every field. Product descriptions often contain many general words, so fuzzy expansion across the full description can produce irrelevant results and increase latency. In many WooCommerce catalogs, the best arrangement is:

  • Product name: enable fuzziness and give the field a strong boost.
  • Short description: enable fuzziness with a lower boost.
  • Long description: use exact or phrase-oriented matching, or omit it from the first-pass query.
  • SKU and product codes: prefer exact matching, with limited fuzzy fallback only when the business case justifies it.
  • Attributes and categories: index normalized keyword and text variants so values such as colors and sizes remain controllable.

Separating these responsibilities is especially important for stores with technical products, where a one-character SKU difference can represent a completely different item.

Combine exact, phrase, and fuzzy matches

A robust search endpoint normally ranks several interpretations of the same query. Exact keyword matches should be strongest, phrase matches should follow, and fuzzy matches should fill gaps for misspellings. A dis_max query can prevent several matches across the same product from inflating the score too aggressively.

{
  "query": {
    "bool": {
      "should": [
        {
          "multi_match": {
            "query": "stainles steel bottle",
            "fields": ["name^6", "short_description^2"],
            "type": "phrase"
          }
        },
        {
          "multi_match": {
            "query": "stainles steel bottle",
            "fields": ["name^4", "short_description"],
            "type": "best_fields",
            "fuzziness": "AUTO",
            "operator": "and",
            "prefix_length": 1
          }
        }
      ],
      "minimum_should_match": 1
    }
  }
}

Using operator: and prevents a product from ranking highly because it matches only one fuzzy token. For longer natural-language searches, a minimum-should-match rule can be more flexible than requiring every token.

Account for WooCommerce analyzers and fields

Fuzzy matching operates on analyzed terms, not on the original unprocessed string. The indexed product field should therefore use an analyzer that supports the store’s language, case normalization, and word boundaries. A typical mapping may expose both a searchable text field and a keyword subfield:

{
  "mappings": {
    "properties": {
      "name": {
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      },
      "sku": {
        "type": "text",
        "fields": {
          "keyword": { "type": "keyword" }
        }
      }
    }
  }
}

When indexing WooCommerce data, normalize values consistently between the product index and the query layer. HTML should be removed from descriptions, variation data should be flattened in a deliberate way, and searchable attribute labels should not be mixed with values unless that behavior is useful for the catalog.

Do not use fuzzy matching for every typo problem

Fuzziness is useful for accidental character errors, but it is not a replacement for synonyms, aliases, transliteration, or business-specific vocabulary. A search for tv and a search for television may require a synonym strategy rather than edit-distance matching. Likewise, brand aliases and common catalog abbreviations should be modeled explicitly.

For autocomplete, consider a separate field using an edge_ngram analyzer or a search_as_you_type field. Fuzzy matching can be expensive on every keystroke, so many implementations use exact prefix suggestions while the shopper is typing and enable fuzzy product search after the query is submitted.

Protect latency and result quality

  • Apply a minimum query length before enabling fuzzy matching; one- or two-character terms generate little useful signal.
  • Use prefix_length and a reasonable max_expansions to limit expansion.
  • Search only the fields needed for the first result page.
  • Set a timeout and return a useful non-fuzzy fallback if Elasticsearch is slow or unavailable.
  • Log the original query, whether fuzzy matching was used, latency, click-through behavior, and zero-result outcomes.
  • Review high-frequency typo queries and add redirects, synonyms, or catalog corrections where fuzzy matching is masking a data problem.

Integrate the behavior in a WooCommerce search endpoint

The WordPress or WooCommerce integration should construct the Elasticsearch query server-side rather than accepting arbitrary field names or query clauses from the browser. Validate the search string, apply store-specific filters such as post_status, stock visibility, language, and product category, then merge the Elasticsearch product IDs with the permissions and pricing rules required by the store.

Keep the fuzzy option configurable per request or per catalog. For example, an agency may enable fuzzy matching for the main product search, disable it for SKU lookup, and use a stricter setting for B2B customers who search by exact part number. Cache popular normalized queries, but include relevant store, language, currency, and visibility context in the cache key.

Test with real catalog queries

Build a test set from search analytics that includes misspellings, brand names, SKUs, product attributes, plural forms, and queries that should return no results. Compare exact-only, fuzzy, and combined queries using metrics such as first-result relevance, zero-result rate, conversion rate, and median response time. A fuzzy query is successful when it recovers genuine intent without allowing unrelated products to outrank exact catalog matches.

Trending posts
You might also like