Skip to content

Latest commit

 

History

History
428 lines (329 loc) · 12.2 KB

File metadata and controls

428 lines (329 loc) · 12.2 KB

🔍 SharpCoreDB Vector Search & Storage

Status:PRODUCTION READY — v1.9.5
Module: SharpCoreDB.VectorSearch (optional, separate NuGet)
Features: HNSW indexes, quantization, distance metrics, GraphRAG integration paths
Performance: 50-100x faster than SQLite vector search
Requirements: .NET 10, C# 14
Breaking Changes: None — backward compatible

v1.9.5 changes

  • Package/docs synchronized to v1.9.5
  • Vector workflows aligned with SharpCoreDB.Graph.Advanced GraphRAG guidance
  • Inherits core metadata/parser reliability improvements from SharpCoreDB v1.9.5

✅ What's Implemented

Vector search in SharpCoreDB is fully implemented and production-ready with:

Core Components

  • HNSW Index - Hierarchical Navigable Small World graphs
  • Distance Metrics - Cosine, Euclidean, Dot Product, Hamming
  • Quantization - Scalar and Binary quantization for memory efficiency
  • Flat Index - Brute-force search for small datasets
  • Vector Serialization - Efficient storage and retrieval
  • SQL Integration - Native vector functions in SQL queries
  • Encryption - AES-256-GCM support for sensitive embeddings

Performance Characteristics

Operation SharpCoreDB SQLite Speedup
Vector Search (cosine, k=10) 0.5-2ms 50-100ms 50-100x
Index Build (1M vectors) 2-5s 60-90s 15-30x
Memory Usage 1-2GB 5-10GB 5-10x less

Note: Performance claims are based on HNSW index characteristics (log-time search) vs SQLite's linear scan behavior. Actual results depend on hardware, vector dimensions, and index parameters. See benchmark code in tests/SharpCoreDB.Benchmarks/VectorSearchPerformanceBenchmark.cs for reproducible results.


What Is Vector Search?

Vector search allows you to store embeddings (high-dimensional float arrays) alongside your regular data and search for semantically similar items using distance metrics like cosine similarity, Euclidean distance, or dot product.

This is the foundation for:

  • AI/RAG applications — Find relevant context for LLM prompts
  • Semantic search — Search by meaning, not just keywords
  • Recommendation engines — Find similar products, articles, or users
  • Anomaly detection — Find items that don't match the pattern
  • Image/audio similarity — Compare media by their embeddings

Why SharpCoreDB Vectors?

Feature SharpCoreDB sqlite-vec pgvector Chroma
Embedded (no server)
Encrypted storage ✅ AES-256-GCM
Pure managed code ✅ C# 14 ❌ (C) ❌ (C) ❌ (Python)
SIMD acceleration ✅ AVX-512/AVX2/NEON
Production-ready HNSW
Cross-platform ✅ 6 RIDs ⚠️ ⚠️
NativeAOT compatible N/A N/A N/A
SQL interface
Scales to RDBMS
Zero dependencies
100% optional N/A

Quick Start

1. Install the Package

# Core database
dotnet add package SharpCoreDB --version 2.0.0

# Vector search extension
dotnet add package SharpCoreDB.VectorSearch --version 2.0.0

2. Register Vector Search

using Microsoft.Extensions.DependencyInjection;
using SharpCoreDB;
using SharpCoreDB.VectorSearch;

var services = new ServiceCollection();
services.AddSharpCoreDB()
    .UseVectorSearch();  // Enable vector search

var provider = services.BuildServiceProvider();
var factory = provider.GetRequiredService<DatabaseFactory>();

using var db = factory.Create("./app_db", "StrongPassword!");

3. Create Vector Schema

// Create vector table
await db.ExecuteSQLAsync(@"
    CREATE TABLE documents (
        id INTEGER PRIMARY KEY,
        content TEXT,
        embedding VECTOR(1536)  -- OpenAI embedding size
    )
");

// Create HNSW index (50-100x faster than Flat)
await db.ExecuteSQLAsync(@"
    CREATE INDEX idx_embedding_hnsw ON documents(embedding)
    USING HNSW WITH (
        metric = 'cosine',
        ef_construction = 200,
        ef_search = 50
    )
");

4. Insert Embeddings

// Single insert
var embedding = new float[] { 0.1f, 0.2f, 0.3f, /* ... 1536 values ... */ };
await db.ExecuteSQLAsync(
    @"INSERT INTO documents (id, content, embedding) 
      VALUES (@id, @content, @embedding)",
    new[] {
        ("@id", (object)1),
        ("@content", (object)"Your document text here"),
        ("@embedding", (object)embedding)
    }
);

// Batch insert (1000+ at a time for performance)
var batch = new List<Dictionary<string, object>>();
for (int i = 0; i < 1000; i++)
{
    batch.Add(new Dictionary<string, object>
    {
        ["id"] = i,
        ["content"] = $"Document {i}",
        ["embedding"] = GenerateEmbedding(i)  // Your embedding function
    });
}
await db.InsertBatchAsync("documents", batch);

5. Semantic Search

// Search for similar documents
var queryEmbedding = new float[] { 0.12f, 0.22f, 0.32f, /* ... */ };
var results = await db.ExecuteQueryAsync(@"
    SELECT 
        id, 
        content,
        vec_distance('cosine', embedding, @query) AS similarity
    FROM documents
    WHERE vec_distance('cosine', embedding, @query) > 0.7
    ORDER BY similarity DESC
    LIMIT 10
",
new[] { ("@query", (object)queryEmbedding) });

foreach (var row in results)
{
    Console.WriteLine($"Doc {row["id"]}: similarity={row["similarity"]:F4}");
}

API Reference

Vector Types

VECTOR(N) Data Type

CREATE TABLE embeddings (
    id INTEGER PRIMARY KEY,
    data VECTOR(384)  -- 384-dimensional embedding
);

Vector Functions

vec_distance(metric, vector1, vector2)

-- Cosine similarity (0 = identical, 2 = opposite)
SELECT vec_distance('cosine', embedding1, embedding2);

-- Euclidean distance (0 = identical, larger = more different)
SELECT vec_distance('euclidean', embedding1, embedding2);

-- Dot product (higher = more similar)
SELECT vec_distance('dot', embedding1, embedding2);

-- Hamming distance (bit differences)
SELECT vec_distance('hamming', embedding1, embedding2);

Index Types

HNSW (Hierarchical Navigable Small World)

CREATE INDEX idx_vectors ON table_name(vector_col)
USING HNSW WITH (
    metric = 'cosine',           -- 'cosine', 'euclidean', 'dot', 'hamming'
    ef_construction = 200,       -- Quality vs build time (100-400)
    ef_search = 50               -- Search parameter (default ~ef_construction/4)
);

Flat (Brute-Force)

CREATE INDEX idx_vectors_flat ON table_name(vector_col)
USING FLAT;  -- Good for <100K vectors

Configuration

VectorSearchOptions

var options = new VectorSearchOptions
{
    // HNSW Configuration
    EfConstruction = 200,      // Higher = better quality, slower build
    EfSearch = 50,             // Higher = better recall, slower search
    MaxConnections = 16,       // Connections per node (5-64)
    
    // Quantization
    QuantizationType = QuantizationType.None,  // None, Scalar, Binary
    ScalarQuantBits = 8,       // 4-8 bits for scalar quantization
    
    // Memory
    MaxMemoryMb = 1024,        // Limit memory usage
    BatchSize = 1000           // Batch insert size
};

services.AddSharpCoreDB()
    .UseVectorSearch(options);

Migration from SQLite Vector Search

Complete 9-step migration guide available: 📖 SQLite Vectors → SharpCoreDB

Key benefits:

  • ⚡ 50-100x faster search
  • 💾 5-10x less memory
  • 🚀 10-30x faster index builds
  • 🔒 Native encryption support
  • 📊 Scales with all SharpCoreDB features

Performance Tuning

Index Parameters

Parameter Impact Default Tuning
ef_construction Quality vs build time 200 Higher (400) for better search quality
ef_search Recall vs search speed 50 Higher for better results, lower for speed
max_connections Graph connectivity 16 Higher (32) for larger datasets

Quantization

// No quantization (maximum accuracy)
options.QuantizationType = QuantizationType.None;

// Scalar quantization (8x less memory, minimal accuracy loss)
options.QuantizationType = QuantizationType.Scalar;
options.ScalarQuantBits = 8;  // 8-bit quantization

// Binary quantization (16x less memory, more accuracy loss)
options.QuantizationType = QuantizationType.Binary;

Batch Operations

// Batch inserts are much faster than single inserts
var batch = documents.Select(doc => new Dictionary<string, object>
{
    ["id"] = doc.Id,
    ["content"] = doc.Text,
    ["embedding"] = doc.Embedding
}).ToList();

await db.InsertBatchAsync("documents", batch);  // 1000+ rows at once

Examples

RAG (Retrieval-Augmented Generation)

public class VectorRAG
{
    private readonly IDatabase _db;
    
    public async Task<List<string>> FindRelevantContext(string query, int topK = 5)
    {
        // Get embedding for query from your LLM API
        var queryEmbedding = await GetEmbeddingAsync(query);
        
        // Search vector database
        var results = await _db.ExecuteQueryAsync(@"
            SELECT content FROM documents
            WHERE vec_distance('cosine', embedding, @query) > 0.7
            ORDER BY vec_distance('cosine', embedding, @query) DESC
            LIMIT @k
        ",
        new[] {
            ("@query", (object)queryEmbedding),
            ("@k", (object)topK)
        });
        
        return results.Select(r => r["content"].ToString()).ToList();
    }
}

Recommendation Engine

public class VectorRecommender
{
    private readonly IDatabase _db;
    
    public async Task<List<int>> GetSimilarItems(int itemId, int topK = 10)
    {
        // Get embedding for the item
        var item = await _db.ExecuteQueryAsync(
            "SELECT embedding FROM items WHERE id = @id",
            new[] { ("@id", (object)itemId) }
        );
        
        if (item.Count == 0) return new();
        
        var itemEmbedding = (float[])item[0]["embedding"];
        
        // Find similar items
        var similar = await _db.ExecuteQueryAsync(@"
            SELECT id FROM items
            WHERE id <> @id
            ORDER BY vec_distance('cosine', embedding, @embedding) ASC
            LIMIT @k
        ",
        new[] {
            ("@id", (object)itemId),
            ("@embedding", (object)itemEmbedding),
            ("@k", (object)topK)
        });
        
        return similar.Select(r => Convert.ToInt32(r["id"])).ToList();
    }
}

Status & Roadmap

Current (v1.1.2) ✅

  • HNSW index implementation
  • Flat (brute-force) index
  • Cosine, Euclidean, Dot Product, Hamming distances
  • Scalar and Binary quantization
  • SQL integration (vec_distance)
  • Encryption support
  • Persistence & recovery
  • Production quality

Future Enhancements (v1.2+)

  • IVFFlat index (coarse partitioning)
  • Product Quantization (PQ)
  • Incremental index builds
  • Vector statistics & analysis functions
  • Approximate nearest neighbor benchmarks

Troubleshooting

Performance Issues

Q: Vector search is slow
A: Check ef_search parameter. Increase from 50 to 100+ for better accuracy. Also verify HNSW index was created (check INFORMATION_SCHEMA).

Q: Memory usage is high
A: Use quantization:

options.QuantizationType = QuantizationType.Scalar;  // 8x less memory

Data Issues

Q: Embedding dimensions don't match
A: Table schema VECTOR(1536) must match actual embedding size (OpenAI=1536, local models vary).

Q: NULL embeddings in results
A: Check your insert statements. NULLs are not indexed and won't appear in distance calculations.


See Also