# How Vector Similarity Search Retrieves Relevant Document Chunks in 5ire

> Discover how 5ire's vector similarity search finds relevant document chunks. It embeds queries, uses HNSW indexing with SQLite, and returns semantically similar results from your local knowledge base.

- Repository: [Ironben/5ire](https://github.com/nanbingxyz/5ire)
- Tags: deep-dive
- Published: 2026-03-07

---

**Vector similarity search in 5ire embeds the user query into a 1024-dimensional vector, calculates cosine distance against stored chunk embeddings using SQLite's HNSW index, and returns the most semantically similar document chunks from the local knowledge base.**

The 5ire application implements a local-first retrieval-augmented generation (RAG) system that stores imported documents as semantically searchable chunks. When you ask a question, the system does not perform keyword matching—it uses **vector similarity search** to find conceptually related content based on embedding geometry. This process runs entirely offline using an SQLite database with a vector extension.

## How the Retrieval Pipeline Works

The `DocumentManager.queryChunks` method in [`src/main/services/document-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/document-manager.ts) orchestrates the complete retrieval flow. The pipeline transforms natural language into mathematical vectors, filters by document scope, and leverages database-native vector operations to rank results by semantic relevance.

### Step 1: Query Embedding

The process begins by converting the user's question into a dense vector representation. The system calls the `Embedder` service to generate a 1024-dimensional embedding using a locally bundled model.

```typescript
// From src/main/services/document-manager.ts (lines 672-779)
const vector = await this.#embedder.embed([options.text]).then((res) => res[0]);

```

This embedding captures the semantic meaning of the query, allowing the system to find conceptually similar content even when keywords differ.

### Step 2: Search Scope Resolution

Before searching, the system determines which documents to include. It accepts optional `documents` and `collections` filters, normalizing them to eliminate duplicates. When collections are specified, the method automatically expands them to include only **completed** documents belonging to those collections.

```typescript
// Scope resolution logic (lines 785-801)
if (collections?.length) {
  const collectionDocs = await this.#database.query.documents.findMany({
    where: and(
      inArray(schema.document.collectionId, collections),
      eq(schema.document.status, "completed")
    ),
  });
  documents = [...new Set([...documents, ...collectionDocs.map(d => d.id)])];
}

```

If the final document list is empty, the method returns immediately with no results.

### Step 3: Cosine Distance Calculation

The core similarity computation uses **cosine distance** to measure the angular difference between the query vector and stored chunk embeddings. A smaller distance indicates higher semantic similarity.

Using Drizzle-ORM, the system constructs a SQL query that:

- Joins `document_chunks` with `documents` to retrieve metadata
- Computes `cosineDistance(schema.documentChunk.embedding, vector)` for each chunk
- Filters by the resolved document set
- Orders results by distance ascending (most similar first)
- Limits results to the specified `limit` (default 10, clamped 1-100)

```typescript
// Vector similarity query construction (lines 859-873)
const chunks = await this.#database.client
  .select({
    id: schema.documentChunk.id,
    text: schema.documentChunk.text,
    url: schema.document.url,
    name: schema.document.name,
    distance: cosineDistance(schema.documentChunk.embedding, vector),
  })
  .from(schema.documentChunk)
  .innerJoin(schema.document, eq(schema.documentChunk.documentId, schema.document.id))
  .where(inArray(schema.documentChunk.documentId, documents))
  .orderBy(cosineDistance(schema.documentChunk.embedding, vector))
  .limit(limit);

```

### Step 4: HNSW Index Acceleration

The database schema defines the `document_chunks` table with a specialized vector column and indexing strategy that makes similarity searches performant at scale.

In [`src/main/database/schema/tables.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/database/schema/tables.ts) (lines 174-221), the schema defines:

```typescript
embedding: vector({ dimensions: 1024 }).notNull(),

```

Additionally, an **HNSW (Hierarchical Navigable Small World)** index accelerates approximate nearest neighbor searches:

```typescript
using("hnsw", table.embedding.op("vector_cosine_ops"))

```

This index structure allows SQLite to perform efficient approximate nearest-neighbor searches on high-dimensional vectors, ensuring that queries remain fast even as the knowledge base grows to thousands of chunks.

## Practical Implementation Examples

### Querying the Knowledge Base from Your Application

The `DocumentManager.queryChunks` method provides a clean API for retrieving relevant chunks:

```typescript
import { DocumentManager } from '@/main/services/document-manager';

const docMgr = new DocumentManager();

async function searchKnowledgeBase() {
  const results = await docMgr.queryChunks({
    text: 'How does vector similarity work?',
    collections: ['c1f2e3d4-5678-90ab-cdef-1234567890ab'],
    limit: 5,
  });

  results.forEach((r) => {
    console.log(`${r.name}: ${r.text.slice(0, 80)}… (dist=${r.distance.toFixed(4)})`);
  });
}

```

### Understanding the Generated SQL

For debugging or optimization purposes, you can inspect the raw SQL generated by Drizzle-ORM:

```typescript
const sql = client
  .select({...})
  .from(schema.documentChunk)
  .innerJoin(...)
  .where(...)
  .orderBy(cosineDistance(schema.documentChunk.embedding, vector))
  .limit(10)
  .toSQL();

console.log(sql.sql);

```

This outputs:

```sql
SELECT document_chunks.id,
       document_chunks.text,
       documents.url,
       documents.name,
       vector_cosine_distance(document_chunks.embedding, ?) AS distance
FROM document_chunks
INNER JOIN documents ON document_chunks.document_id = documents.id
WHERE document_chunks.document_id IN (?, ?)
ORDER BY vector_cosine_distance(document_chunks.embedding, ?)
LIMIT 10

```

## Summary

- **Vector similarity search** in 5ire converts queries and documents into 1024-dimensional embeddings to enable semantic matching beyond keywords.
- The `DocumentManager.queryChunks` method orchestrates the retrieval by embedding the query, resolving document scope, and executing a cosine distance calculation via Drizzle-ORM.
- **Cosine distance** measures semantic similarity, with results ordered from most similar (lowest distance) to least similar.
- The **HNSW index** on the `embedding` column in [`src/main/database/schema/tables.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/database/schema/tables.ts) ensures efficient approximate nearest-neighbor search performance at scale.
- All operations run locally using SQLite with the vector extension, requiring no external vector database services.

## Frequently Asked Questions

### What embedding model does 5ire use for vector similarity search?

The `Embedder` service uses a locally bundled model to generate 1024-dimensional vectors. According to the source code in [`src/main/services/document-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/document-manager.ts), the system calls `this.#embedder.embed([options.text])` to transform query text into dense embeddings suitable for cosine similarity comparison.

### How does 5ire handle large knowledge bases efficiently?

The application leverages an **HNSW (Hierarchical Navigable Small World)** index defined in [`src/main/database/schema/tables.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/database/schema/tables.ts). This index structure enables approximate nearest-neighbor search on high-dimensional vectors, allowing the system to retrieve semantically similar chunks in milliseconds even when the database contains thousands of document segments.

### Can I filter vector similarity search results by specific documents or collections?

Yes. The `queryChunks` method accepts optional `documents` and `collections` parameters. When provided, the system normalizes these filters and restricts the cosine distance calculation to chunks belonging only to the specified documents or completed documents within the specified collections, as implemented in lines 785-805 of [`src/main/services/document-manager.ts`](https://github.com/nanbingxyz/5ire/blob/main/src/main/services/document-manager.ts).

### What distance metric indicates the best match in the search results?

The system uses **cosine distance** to rank results, where a **lower value indicates higher semantic similarity**. A distance of 0.0 represents identical vectors, while larger values indicate decreasing relevance. The results are automatically ordered by this distance in ascending order, placing the most relevant chunks first.