Table of Contents

Vector Database Overview

Mythosia.AI provides a unified IVectorStore abstraction that works across multiple vector database backends. You write your application against the interface once and swap backends without changing any retrieval logic.

Core Interface: IVectorStore

// Upsert
Task UpsertAsync(VectorRecord record, CancellationToken cancellationToken = default);
Task UpsertBatchAsync(IEnumerable<VectorRecord> records, CancellationToken cancellationToken = default);

// Search
Task<IReadOnlyList<VectorSearchResult>> SearchAsync(
    float[] queryVector, int topK = 5, VectorFilter? filter = null,
    CancellationToken cancellationToken = default);

Task<IReadOnlyList<VectorSearchResult>> HybridSearchAsync(
    float[] denseVector, string query, int topK = 5, VectorFilter? filter = null,
    CancellationToken cancellationToken = default);

// Get by ID
Task<VectorRecord?> GetAsync(string id, VectorFilter? filter = null,
    CancellationToken cancellationToken = default);
Task<IReadOnlyList<VectorRecord>> GetBatchAsync(IEnumerable<string> ids,
    VectorFilter? filter = null, CancellationToken cancellationToken = default);

// Delete
Task DeleteAsync(string id, VectorFilter? filter = null,
    CancellationToken cancellationToken = default);
Task DeleteByFilterAsync(VectorFilter filter, CancellationToken cancellationToken = default);
Task ReplaceByFilterAsync(VectorFilter filter, IReadOnlyList<VectorRecord> records,
    CancellationToken cancellationToken = default);

// Utility
Task<long> CountAsync(VectorFilter? filter = null, CancellationToken cancellationToken = default);
Task VerifyConnectionAsync(CancellationToken cancellationToken = default);

Data Models

VectorRecord

Every stored entry is a VectorRecord:

public class VectorRecord
{
    public string Id { get; set; }                           // Unique identifier
    public float[] Vector { get; set; }                      // Embedding vector
    public string Content { get; set; }                      // Original text content
    public Dictionary<string, string> Metadata { get; set; } // Custom key-value metadata
}

Use the Metadata dictionary for any custom fields — source file, language, date, category, etc.:

var record = new VectorRecord
{
    Id = Guid.NewGuid().ToString(),
    Vector = await embeddingService.GetEmbeddingAsync("Some text"),
    Content = "Some text",
    Metadata = new Dictionary<string, string>
    {
        ["source"] = "manual.pdf",
        ["language"] = "en",
        ["date"] = "2024-01-15",
        ["category"] = "policy"
    }
};

VectorSearchResult

Search results pair a record with its similarity score:

public class VectorSearchResult
{
    public VectorRecord Record { get; set; }
    public double Score { get; set; }  // 0.0–1.0 (higher = more similar)
}

Available Backends

Backend Package Use Case
In-Memory Mythosia.VectorDb.InMemory Development, testing, demos
Qdrant Mythosia.VectorDb.Qdrant Production, native hybrid search
Pinecone Mythosia.VectorDb.Pinecone Serverless managed service
PostgreSQL Mythosia.VectorDb.Postgres Existing Postgres deployments, ACID

All backends implement the same IVectorStore interface. See Backend Setup for per-backend configuration.

Dependency Injection

Register any backend as IVectorStore:

// In-Memory
services.AddSingleton<IVectorStore>(new InMemoryVectorStore());

// Qdrant
services.AddSingleton<IVectorStore>(new QdrantStore(new QdrantOptions
{
    CollectionName = "my-collection",
    Dimension = 1536
}));

// PostgreSQL
services.AddSingleton<IVectorStore>(new PostgresStore(new PostgresOptions
{
    ConnectionString = "Host=localhost;Database=vectors;",
    Dimension = 1536,
    EnsureSchema = true
}));

Filter Execution by Backend

VectorFilter conditions are pushed down to the backend where possible:

Operator InMemory Qdrant Pinecone Postgres
Eq / Ne Client Server Server SQL
In / NotIn Client Server Server SQL
Gt / Gte / Lt / Lte Client Client Server SQL
Like Client Client Client SQL
Exists / NotExists Client Client Client SQL

Postgres has full SQL pushdown for all operators. Qdrant and Pinecone push down equality, set membership, and comparison operators natively.

Note: Qdrant silently drops unsupported filter operators (Like, Exists, NotExists) — they are not applied client-side. If you need these operators with Qdrant, apply additional filtering on the returned results.