---
title: "Typo-tolerant search in C#"
url: https://recursiveai.org/oneindex/cookbook/typo-tolerant-search/
description: "Find documents despite misspelled search text in C# with OneIndex. Compare strict search, configure typo thresholds, and exclude words or fields."
version: "0.4.0-preview.2"
---

# Typo-tolerant search in C#

**OneIndex** is a free, open-source search library for .NET from Recursive AI. MIT or Apache-2.0, preview, runs in-process.

[NuGet](https://www.nuget.org/packages/RecursiveAI.OneIndex) · [GitHub](https://github.com/recursive-ai-oss/oneindex-csharp) · [Docs](https://recursiveai.org/oneindex/docs/) · [Download example (.zip)](https://recursiveai.org/oneindex/cookbook/typo-tolerant-search/typo-tolerant-search.zip)

```shell
dotnet add package RecursiveAI.OneIndex --prerelease
```

Requires [.NET 10](https://dotnet.microsoft.com/download/dotnet/10.0) (net10.0); .NET 9 and earlier aren’t supported.

```csharp
using OneIndex;
using var index =
    SearchIndex.InMemory<Note>();
index.Upsert(new Note
    { Id = "1", Title = "Quick brown fox" });
index.Commit();
// trailing space = finished word, not a prefix
foreach (var hit in index.Search("quikc "))
    Console.WriteLine(hit.Document.Title);
Console.WriteLine("Strict matches: " +
    index.SearchStrict("quikc").Count());
public class Note
{
    [SearchId]
    public string Id { get; set; } = "";
    [FullText]
    public string Title { get; set; } = "";
}
```

```text
Quick brown fox
Strict matches: 0
```

This example uses preview 0.4.0-preview.2; APIs and file formats may change between previews.

The input is the title `Quick brown fox`, created in the program. The query `quikc ` swaps two adjacent letters. Its trailing space makes it a completed word rather than a prefix being typed.

Unzip [the example](https://recursiveai.org/oneindex/cookbook/typo-tolerant-search/typo-tolerant-search.zip), then `dotnet run`.

## Variations

Add this attribute above `Note` in the full program, and add `[FullText] public string Code { get; set; } = "";` inside the class. It lowers the thresholds but excludes `quikc`, the `Code` field, and all-digit words from typo matching:

```csharp
[TypoTolerance(MinWordSizeForOneTypo = 4,
    MinWordSizeForTwoTypos = 8,
    DisableOnWords = ["quikc"],
    DisableOnFields = ["Code"],
    DisableOnNumbers = true)]
```

Invalid thresholds throw `ArgumentException`; strict syntax errors throw `QueryParseException` rather than falling back to forgiving search.

`Search("quikc ")` now returns no hits, so the output is only `Strict matches: 0`.

```text
Strict matches: 0
```

## Related recipes

[Faceted search in C#](https://recursiveai.org/oneindex/cookbook/faceted-search/) · [“Did you mean” search suggestions in C#](https://recursiveai.org/oneindex/cookbook/suggest-query-corrections/) · [Full-text search](https://recursiveai.org/oneindex/cookbook/full-text-search-csharp/)

---

## The short answer

Use `index.Search(userText)` to return documents for misspelled text in C#. `Search()` handles typos in what users type; `SearchStrict()` does not. `SearchStrict` and query JSON do not inherit those settings: they keep explicit fuzzy-query syntax. The example returns `Quick brown fox` for `quikc `, while the strict query for `quikc` returns no hits.

This is matching, not query correction. The user’s original text can remain in the search box while matching documents appear below it. The behavior and defaults are specified in [Typo tolerance](https://recursiveai.org/oneindex/docs/typo-tolerance/).

## How do I find common typos of strings in C# .NET?

For indexed document search, query the dictionary of indexed words rather than comparing the query with every full document string yourself. OneIndex analyzes the query and checks candidate words against a per-word typo budget. An insertion, deletion, substitution, or adjacent-character swap costs one edit. If the first character differs, an extra typo is charged.

The default budget is zero for words shorter than five code points, one from five, and two from nine. It never exceeds two. These lengths refer to analyzed words, so stemming can shorten a word before the budget is chosen. A first-letter error in a five-letter word therefore does not fit the default one-typo allowance, even if it looks like a single substitution to the user.

The last word is normally treated as a prefix still being typed. That is why the sample deliberately includes a trailing space: the transposed word is searched as a completed word. A trailing quote, a quoted word, an excluded word, or disabled prefix search can also prevent the as-you-type behavior. A short prefix can match the beginning of a longer word without needing any typo allowance.

Strict queries serve a different purpose. They preserve a deliberate query language, including explicit fuzzy terms such as `word~1`. Changing `[TypoTolerance]` does not change that parser’s meaning. Keep normal search-box input on `Search` unless your UI actually exposes the strict language and handles its parse errors.

## Is typo-tolerant search free?

OneIndex’s typo matching is included in the free, open-source NuGet package used here. The example runs in memory without a search service. This page uses preview 0.4.0-preview.2, not a stable API promise; the project states that APIs and file formats may change between previews.

Free matching still needs configuration appropriate to the content. Lowering the one-typo threshold can make short words match more unintended terms. The variation enables one typo from four characters and two from eight, while excluding the query word `quikc`, a field named `Code`, and all-digit words. The excluded query no longer returns the title. Put these attributes on the document type before creating the index; they are schema settings, not an instruction to rewrite the user’s query.

`DisableOnWords` compares without case sensitivity against both the analyzed and typed word. `DisableOnFields` keeps matches in the named fields exact with respect to typos. `DisableOnNumbers` is useful when neighboring numeric strings must not count as spelling variants. Prefix matching is a separate setting, so disabling typos should not be mistaken for disabling prefixes. Review the [user-text rules](https://recursiveai.org/oneindex/docs/user-text/) when combining these options with quotes, exclusions, or fields.
