# How to Implement Autocomplete Suggestions While Preserving Scoring Accuracy in FlexSearch

> Implement FlexSearch autocomplete suggestions with { suggest: true } to preserve scoring accuracy. Get fallback suggestions only after exact matches fail, ensuring relevance.

- Repository: [Nextapps GmbH/flexsearch](https://github.com/nextapps-de/flexsearch)
- Tags: how-to-guide
- Published: 2026-02-23

---

**Enable `{ suggest: true }` in your search options to activate FlexSearch's fallback suggestion mode, which only triggers after exact matching fails and preserves the original relevance scoring algorithm for all returned results.**

FlexSearch is a high-performance full-text search library that balances speed with relevance. When building autocomplete functionality, developers often worry that enabling suggestions will compromise the accuracy of result ranking. The library's suggestion mode is specifically designed to preserve scoring accuracy by only activating as a fallback mechanism when exact queries return no matches, ensuring that your autocomplete suggestions maintain the same relevance ordering as standard searches.

## How Suggestion Mode Works in FlexSearch

The suggestion functionality lives in [`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js) and operates as a lightweight fallback rather than an alternative search path. When you pass `{ suggest: true }` to the search method, FlexSearch first executes a normal strict search. Only if that search returns zero results does the engine enter suggestion mode.

### The Fallback Trigger Mechanism

The suggestion flag is read from the options object at the beginning of the search execution:

```javascript
suggest = SUPPORT_SUGGESTION && options.suggest;

```

According to the source code in [`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js) (lines 68-71), this boolean determines whether the engine can enter fallback mode. When a multi-term query finishes without any hits, FlexSearch detects this condition at lines 75-84 and enters a fallback loop that resets the resolution and keyword before restarting the term iteration. This design ensures that the **normal relevance scoring**—including term frequency, resolution handling, and context awareness—is fully applied to the original query before any fallback occurs.

### Resolution and Context Preservation

The scoring accuracy is maintained through careful state management during the fallback transition:

- **Resolution handling**: During normal search, the engine uses `this.resolution` (or `resolution_ctx` for contextual searches) to determine how many top-ranked documents to retain per term (lines 30-34). When the fallback triggers, the resolution is reset to `this.resolution` (lines 77-79), ensuring the same ranking thresholds apply to suggestion results.

- **Context management**: In normal operation, the context keyword advances only when a term produces results (lines 14-22, 65-72). During fallback, the context is cleared (`keyword = ""`) so the engine can search without context constraints, but this only happens after all normal attempts have been exhausted.

- **Scoring consistency**: Whether returning exact matches or suggestions, the final results pass through the same `intersect()` function (found in [`src/intersect.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/intersect.js)) which applies the resolution-based scoring algorithm. The fallback re-runs this identical logic on newly gathered results, ensuring no degradation in ranking quality.

## Implementing Autocomplete with Accurate Scoring

To implement autocomplete suggestions while preserving FlexSearch's relevance scoring, initialize your index with appropriate tokenization and enable the suggestion flag only when needed.

### Basic Index Configuration

Create an index with strict tokenization and context support, then enable suggestions for fallback queries:

```javascript
import FlexSearch from "flexsearch";

const index = new FlexSearch.Index({
  tokenize: "strict",          // exact tokenization
  resolution: 10,              // keep top-10 matches per term
  context: { depth: 3, bidirectional: true } // optional context support
});

// Add documents (id → content)
index.add(0, "1 2 3 2 4 1 5 3");
index.add(1, "zero one two three four five six seven eight nine ten");
index.add(2, "four two zero one three ten five seven eight six nine");

// Strict search returns empty array when no exact match exists
console.log(index.search("1 3 4 7")); // → []

// Suggestion mode returns the most relevant document
console.log(index.search("1 3 4 7", { suggest: true })); // → [0]

```

In this example, the engine first attempts a strict search for the exact terms "1", "3", "4", and "7". Finding no document containing all terms, it falls back to suggestion mode and returns document 0 because it contains the highest frequency of the individual query terms, preserving the relevance scoring that ranked it highest.

### UI Integration with Ranked Results

When building an autocomplete interface, use the `resolve` option to receive a plain array of document IDs ordered by relevance:

```javascript
function onInputChange(term) {
  // Request up to 5 suggestions maintaining relevance order
  const suggestions = index.search(term, {
    suggest: true,   // enable fallback suggestions
    limit: 5,        // cap number of returned IDs
    resolve: true    // return plain array, not a Resolver object
  });

  // suggestions is an ordered list of document IDs
  renderAutocomplete(suggestions);
}

```

Setting `resolve: true` ensures FlexSearch returns the ranked array directly from the `resolve_default` function in [`src/resolve/default.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/resolve/default.js), allowing your UI to display suggestions ordered by the same scoring algorithm used for exact matches.

### Retrieving Scores with Document Enrichment

To access the actual relevance scores alongside document IDs, use the `enrich` option:

```javascript
const records = {
  0: { title: "First", content: "1 2 3 2 4 1 5 3" },
  1: { title: "Second", content: "zero one two three four five six seven eight nine ten" },
  2: { title: "Third", content: "four two zero one three ten five seven eight six nine" }
};

function searchWithDetails(query) {
  // enrich: true returns [{ id, doc, score }]
  const results = index.search(query, { suggest: true, enrich: true });

  // Attach original document data while preserving score
  return results.map(r => ({
    ...r,
    record: records[r.id]
  }));
}

```

The suggestion fallback still executes the final `intersect()` step, which computes a **score** for each hit based on term frequency and resolution settings. By enabling `enrich`, you receive this score metadata alongside the document ID, giving you full visibility into how FlexSearch ranked your autocomplete suggestions.

## Key Source Files for Scoring Accuracy

Understanding these core files helps verify that suggestion mode preserves scoring accuracy:

- **[`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js)**: Contains the core search implementation including the suggestion fallback logic (lines 75-84), resolution handling, and the conditional that checks `if (suggest && keyword && (index === length - 1))` before entering fallback mode.

- **[`src/intersect.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/intersect.js)**: Implements the intersection and scoring algorithm applied to multi-term results. This same function processes results whether they come from exact matching or suggestion fallback.

- **[`src/config.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/config.js)**: Defines the `SUPPORT_SUGGESTION` feature toggle that enables the suggestion functionality at build time.

- **[`src/resolve/default.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/resolve/default.js)**: Houses the `resolve_default` function that produces the final ranked array, used consistently after both normal searches and suggestion fallbacks.

- **[`test/scoring.js`](https://github.com/nextapps-de/flexsearch/blob/main/test/scoring.js)**: Contains the test suite verifying that scoring behavior remains consistent when suggestion mode is active.

## Summary

- **Suggestion mode is a fallback**: FlexSearch only activates `suggest: true` after the normal search path returns zero results, ensuring exact matches always receive priority ranking.

- **Scoring algorithm remains unchanged**: The same `intersect()` function and resolution-based scoring apply to both exact matches and suggestions, as implemented in [`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js).

- **Context and resolution are reset, not modified**: When falling back, the engine clears context (`keyword = ""`) and resets resolution to `this.resolution`, but uses the identical scoring pipeline to rank results.

- **Enrich option exposes scores**: Use `{ enrich: true }` to access relevance scores even when using suggestion mode, confirming that ranking accuracy is preserved.

## Frequently Asked Questions

### Does enabling suggestion mode slow down normal searches?

No. The suggestion flag is checked only after the normal search completes without results. According to [`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js), the condition `if (suggest && keyword && (index === length - 1))` is evaluated only when the term iteration finishes with no hits. Normal searches that return matches never enter the fallback loop, so performance characteristics remain identical for exact match queries.

### How does FlexSearch handle context when falling back to suggestions?

When the fallback triggers, the engine clears the context keyword by setting `keyword = ""` (visible in [`src/index/search.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/index/search.js) lines 77-79). This allows the search to proceed without context constraints, effectively broadening the query to find partial matches. However, this only occurs after all contextual search attempts have failed, ensuring that context-aware exact matches maintain their priority in the results.

### What is the difference between suggestion mode and fuzzy matching?

Suggestion mode (`{ suggest: true }`) operates at the query execution level by relaxing the requirement that all terms must match, instead returning documents that contain the best subset of terms. Fuzzy matching operates at the index level, allowing character-level variations in individual terms. You can combine both approaches, but suggestion mode specifically preserves scoring accuracy by reusing the standard intersection algorithm while fuzzy matching uses edit-distance calculations in the index.

### Can I customize the scoring algorithm when using autocomplete suggestions?

The scoring algorithm is fixed in the `intersect()` function located in [`src/intersect.js`](https://github.com/nextapps-de/flexsearch/blob/main/src/intersect.js), which applies resolution-based ranking to all results regardless of whether they come from exact matching or suggestion fallback. While you cannot override the internal scoring without modifying the source, you can use the `enrich` option to retrieve raw scores and implement additional ranking layers in your application logic based on business requirements.