# How Fuzzy Search Differs from Semantic Search in the Egonex Knowledge Graph

> Discover how fuzzy search's approximate string matching contrasts with semantic search's conceptual understanding using vector embeddings in the Egonex knowledge graph. Learn the key differences.

- Repository: [Egonex/Understand-Anything](https://github.com/Egonex-AI/Understand-Anything)
- Tags: deep-dive
- Published: 2026-06-21

---

**Fuzzy search in Egonex uses Fuse.js for approximate string matching against node text fields, while semantic search computes cosine similarity between dense vector embeddings to capture conceptual meaning.**

The Egonex *Understand-Anything* plugin provides two distinct search modes for exploring the knowledge graph. Understanding how fuzzy search differs from semantic search in the Egonex knowledge graph helps developers choose the right approach for typo-tolerant lookups versus meaning-based discovery. Both engines are implemented in the core package, but they differ fundamentally in algorithms, data requirements, and use cases.

## Algorithmic Foundations

The two search modes employ fundamentally different approaches to matching queries against graph nodes.

### Fuzzy Search Implementation

**Fuzzy search** relies on Fuse.js to perform approximate string matching. The engine tokenizes the query, builds an extended "OR" query (e.g., converting `auth contrl` into `auth | contrl`), and scores results by textual similarity. This approach indexes the node fields **name**, **tags**, **summary**, and **languageNotes** with descending weights (0.4 → 0.1) according to the source code in [`packages/core/src/search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/search.ts).

The search method returns a list of `{nodeId, score}` objects where `score` represents the Fuse-derived relevance (0 indicates a perfect match). This method requires no pre-computed embeddings and operates purely on textual data present in the graph.

### Semantic Search Implementation

**Semantic search** computes **cosine similarity** between dense vector embeddings of graph nodes and the query embedding. Implemented in [`packages/core/src/embedding-search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/embedding-search.ts), the custom `SemanticSearchEngine` stores node embeddings in a `Map` structure and calculates similarity using the `cosineSimilarity` function (lines 14-30).

Unlike fuzzy matching, this approach captures semantic relationships, synonyms, and paraphrases by comparing high-dimensional vectors. The engine returns the top-k nodes whose similarity exceeds a configurable threshold, enabling discovery of conceptually related nodes that share little lexical overlap.

## Implementation Details and File Structure

The architecture separates concerns between text-based and vector-based search:

| File | Purpose |
|------|---------|
| [`packages/core/src/search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/search.ts) | Implements the fuzzy `SearchEngine` using Fuse.js (lines 14-25, 36-59) |
| [`packages/core/src/embedding-search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/embedding-search.ts) | Implements `SemanticSearchEngine` and `cosineSimilarity` for vector-based search (lines 14-30, 37-78) |
| [`packages/dashboard/src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/store.ts) | Holds the UI state (`searchMode`), creates the appropriate engine, and dispatches searches (lines 111-112, 519-531) |
| [`packages/dashboard/src/components/SearchBar.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/components/SearchBar.tsx) | UI component that lets the user type a query and switch between fuzzy/semantic modes (lines 217-289) |

## Data Requirements and Performance Characteristics

Each search mode presents distinct trade-offs in data preparation and computational overhead.

### Fuzzy Search Advantages and Limitations

**Strengths:**
- Fast, deterministic execution with no external model dependencies
- Excellent for exact-ish name and tag lookups with typo tolerance
- Zero preprocessing required—works immediately on graph text fields

**Limitations:**
- Cannot capture relationships not expressed in searchable strings
- Scores derive from string distance metrics, not semantic meaning
- Misses conceptual connections between synonyms or related terms

### Semantic Search Advantages and Limitations

**Strengths:**
- Captures semantic similarity across languages and paraphrases
- Surfaces conceptually related nodes despite minimal lexical overlap
- Enables discovery based on meaning rather than exact text matching

**Limitations:**
- Requires embedding generation, incurring computational cost
- Quality depends entirely on the embedding model
- Empty or low-quality embeddings produce poor or irrelevant results

## Runtime Switching and UI Integration

The dashboard implements a runtime toggle between these modes using Zustand state management. In [`packages/dashboard/src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/store.ts) (lines 111-112), the store maintains `searchMode: "fuzzy" | "semantic"` with `"fuzzy"` as the default.

When users switch modes via the search bar UI ([`packages/dashboard/src/components/SearchBar.tsx`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/components/SearchBar.tsx)), the application instantiates the appropriate engine. For semantic mode, the dashboard creates a `SemanticSearchEngine` instance (if embeddings exist) and calls its `.search` method; otherwise, it falls back to the fuzzy `SearchEngine`.

## Practical Code Examples

### Fuzzy Search Implementation

```typescript
import { SearchEngine } from "@understand-anything/core/search";

// `graph.nodes` is an array of GraphNode objects.
const fuzzyEngine = new SearchEngine(graph.nodes);

// Basic query – fuzzy-matches name / summary / tags.
const fuzzyResults = fuzzyEngine.search("auth contrl", {
  limit: 10,
  types: ["function"], // optional filter
});

```

### Semantic Search Implementation

```typescript
import {
  SemanticSearchEngine,
  cosineSimilarity,
} from "@understand-anything/core/embedding-search";

// `embeddings` is a Record<string, number[]> keyed by node ID.
const semanticEngine = new SemanticSearchEngine(graph.nodes, embeddings);

// Assume `queryEmbedding` is obtained from an LLM for the user query.
const semanticResults = semanticEngine.search(queryEmbedding, {
  limit: 10,
  threshold: 0.6,          // only return > 60% similarity
  types: ["function"],     // optional node-type filter
});

```

### Toggle Implementation in Dashboard Store

```typescript
// ... in the Zustand store definition
searchMode: "fuzzy", // default

// Switch mode (e.g. from UI)
setSearchMode: (mode) => set({ searchMode: mode }),

// When performing a search:
const engine = get().searchEngine!;
const mode = get().searchMode;

if (mode === "semantic" && engine instanceof SemanticSearchEngine) {
  const results = engine.search(queryEmbedding);
  // …
} else {
  const results = engine.search(queryString);
  // …
}

```

## Summary

- **Fuzzy search** in [`packages/core/src/search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/search.ts) uses Fuse.js for approximate string matching against node text fields (name, tags, summary, languageNotes), providing fast, typo-tolerant results without requiring embeddings.
- **Semantic search** in [`packages/core/src/embedding-search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/embedding-search.ts) implements vector-based cosine similarity comparison to capture conceptual meaning, requiring pre-computed embeddings but enabling cross-lingual and synonym-aware discovery.
- The **dashboard store** ([`packages/dashboard/src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/store.ts)) manages runtime switching between modes via Zustand, defaulting to fuzzy search for immediate results while allowing semantic mode for deeper meaning-based exploration.
- **Algorithmic choice** depends on use case: fuzzy for exact lookups with tolerance for typos, semantic for conceptual relationships and language-agnostic similarity.

## Frequently Asked Questions

### How does the Egonex knowledge graph handle the transition between fuzzy and semantic search modes?

The transition occurs through the Zustand store defined in [`packages/dashboard/src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/store.ts). The store maintains a `searchMode` state that toggles between `"fuzzy"` and `"semantic"` values. When the mode changes, the application instantiates the appropriate engine—either the Fuse.js-based `SearchEngine` or the vector-based `SemanticSearchEngine`—and routes queries accordingly, allowing seamless switching without page reloads.

### What specific fields does the fuzzy search engine index in the Egonex knowledge graph?

According to the implementation in [`packages/core/src/search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/search.ts), the fuzzy search engine indexes four specific node fields: **name** (weight 0.4), **tags** (weight 0.3), **summary** (weight 0.2), and **languageNotes** (weight 0.1). These descending weights ensure that matches in node names rank higher than matches in supplementary notes.

### Why might semantic search return poor results in the Egonex Understand-Anything plugin?

Semantic search quality depends entirely on the availability and quality of pre-computed embeddings for each graph node. If nodes lack embeddings, were processed with a low-quality model, or contain empty vectors, the `cosineSimilarity` calculation in [`packages/core/src/embedding-search.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/core/src/embedding-search.ts) cannot establish meaningful relationships. Additionally, the configurable threshold (typically 0.6) may filter out results if the query embedding diverges significantly from stored node vectors.

### Can I use both search modes simultaneously in the Egonex dashboard?

The current implementation in [`packages/dashboard/src/store.ts`](https://github.com/Egonex-AI/Understand-Anything/blob/main/packages/dashboard/src/store.ts) treats these modes as mutually exclusive via the `searchMode` state. However, the architecture allows you to instantiate both `SearchEngine` and `SemanticSearchEngine` concurrently in custom implementations, merging results from both `fuzzyEngine.search()` and `semanticEngine.search()` calls to create hybrid ranking systems.