Mythosia.VectorDb.Abstractions 4.2.0

dotnet add package Mythosia.VectorDb.Abstractions --version 4.2.0
                    
NuGet\Install-Package Mythosia.VectorDb.Abstractions -Version 4.2.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Mythosia.VectorDb.Abstractions" Version="4.2.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Mythosia.VectorDb.Abstractions" Version="4.2.0" />
                    
Directory.Packages.props
<PackageReference Include="Mythosia.VectorDb.Abstractions" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Mythosia.VectorDb.Abstractions --version 4.2.0
                    
#r "nuget: Mythosia.VectorDb.Abstractions, 4.2.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Mythosia.VectorDb.Abstractions@4.2.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Mythosia.VectorDb.Abstractions&version=4.2.0
                    
Install as a Cake Addin
#tool nuget:?package=Mythosia.VectorDb.Abstractions&version=4.2.0
                    
Install as a Cake Tool

Mythosia.VectorDb.Abstractions

v4.2.0: Adds optional IVectorStoreDiagnostics for record inspection and all-record similarity scores without a RAG dependency. Existing IVectorStore implementations gain no required members. See the release notes.

Core contracts for the Mythosia VectorDb abstraction layer. Defines IVectorStore, optional IVectorStoreDiagnostics, all model types, and the metadata-based filtering API. Consumed by Mythosia.AI.Rag and all concrete store implementations (InMemory, Postgres, Qdrant, Pinecone).

Breaking change in v4.0.0

VectorRecord.Namespace, VectorRecord.Scope, VectorFilter.Namespace, VectorFilter.Scope, VectorFilter.WithNamespace(), INamespaceContext, IScopeContext, and InNamespace() / InScope() were removed in v4.0.0. Calls to these APIs must be migrated before upgrading.

Use Metadata for logical isolation instead. Store partition keys (namespace, scope, tenant, etc.) as metadata entries and filter them with VectorFilter.Where("key", "value"). This aligns with industry-standard vector database designs (Qdrant payload, Pinecone metadata, LangChain PGVector).

// Before v4.0.0 (historical example; these APIs no longer compile)
record.Namespace = "docs";
record.Scope = "tenant-1";
var filter = new VectorFilter { Namespace = "docs", Scope = "tenant-1" };

// v4.0.0 and later
record.Metadata["namespace"] = "docs";
record.Metadata["scope"] = "tenant-1";
var filter = new VectorFilter().Where("namespace", "docs").Where("scope", "tenant-1");

Filter operator coverage vs. industry libraries

Operator Pinecone Weaviate¹ Chroma Semantic Kernel² Mythosia
Eq ✓ ✓ ✓ ✓ ✓
Ne ✓ ✓ ✓ ✓ ✓
Gt / Gte ✓ ✓ ✓ ✓ ✓
Lt / Lte ✓ ✓ ✓ ✓ ✓
In ✓ ✓ (v1.22+) ✓ ✓ ✓
NotIn ✓ — ✓ — ✓
Like — ✓ (* wildcard) — — ✓ (% / _)
Exists / NotExists — — — — ✓
And / Or groups ✓ ✓ ✓ ✓ ✓

¹ Weaviate ContainsAny (v1.22+) maps to In. Wildcard Like uses * not %. ² Semantic Kernel's VectorSearchFilter is a framework abstraction; operator availability depends on the underlying store connector.


Installation

dotnet add package Mythosia.VectorDb.Abstractions

Install this package directly only when writing a custom IVectorStore implementation or when consuming the interface in a library. Applications normally take a transitive dependency through a concrete store package.


Core Types

VectorRecord

The unit of storage. Holds the embedding vector, content text, and metadata. Store logical isolation keys in metadata.

var record = new VectorRecord
{
    Id        = "doc-1",
    Vector    = new float[] { 0.1f, 0.2f, 0.3f },
    Content   = "Original text content",
    Metadata  = new Dictionary<string, string>
    {
        ["source"]    = "manual.txt",
        ["namespace"] = "my-namespace",  // logical isolation via metadata
        ["scope"]     = "tenant-1"       // logical isolation via metadata
    }
};
Property Type Description
Id string Unique record ID (globally unique, GUID-based)
Vector float[] Embedding vector
Content string Original text (nullable in some stores)
Metadata Dictionary<string, string> Arbitrary key-value pairs for filtering/display

VectorFilter

Fluent criteria builder for scoping searches, gets, deletes, and counts. Top-level conditions are AND-combined by default. Use .And() / .Or() for explicit logical grouping.

Comparison operators
var filter = new VectorFilter()
    .Where("category", "policy")               // Eq  — exact match
    .WhereNot("status", "archived")            // Ne
    .WhereGreaterThan("year", "2023")          // Gt
    .WhereGreaterThanOrEqual("year", "2023")   // Gte
    .WhereLessThan("priority", "5")            // Lt
    .WhereLessThanOrEqual("priority", "5")     // Lte
    .WhereIn("type", "pdf", "docx", "txt")     // In
    .WhereNotIn("lang", "zh", "ja")            // NotIn
    .WhereLike("title", "%report%")            // LIKE — % and _ wildcards
    .WhereExists("thumbnail")                  // key must be present
    .WhereNotExists("deleted_at");             // key must be absent
Logical grouping
// OR group: (type = 'policy' OR type = 'manual')
var filter = new VectorFilter()
    .Or(g => g
        .Where("type", "policy")
        .Where("type", "manual")
    );

// Nested AND inside OR: (a=1 OR (b=2 AND c=3))
var filter = new VectorFilter()
    .Or(g => g
        .Where("a", "1")
        .And(inner => inner
            .Where("b", "2")
            .Where("c", "3")
        )
    );
Metadata isolation and score filtering
// Use Where() for metadata filtering, including namespace/scope
var filter = new VectorFilter()
    .Where("namespace", "docs")
    .Where("scope", "tenant-1")
    .Where("lang", "ko")
    .WithMinScore(0.75);
Property Type Description
Conditions IReadOnlyList<FilterCondition> Top-level condition tree (AND-combined)
MinScore double? Exclude search results below this score; its scale depends on the search mode
Operator InMemory Postgres Qdrant Pinecone
Eq ✓ ✓ (JSONB @>) ✓ ✓ ($eq)
Ne ✓ ✓ ✓ ✓ ($ne)
Gt / Gte / Lt / Lte ✓ ✓ — ✓ ($gt etc.)
In ✓ ✓ (= ANY(...)) ✓ ✓ ($in)
NotIn ✓ ✓ ✓ ✓ ($nin)
Like ✓ ✓ (LIKE) — —
Exists / NotExists ✓ ✓ (jsonb_exists) — —
And / Or groups ✓ ✓ ✓ ✓

Qdrant and Pinecone silently skip unsupported operators during server-side filter translation for SearchAsync and the HybridSearchAsync overload without HybridSearchOptions; MatchesFilter in both stores evaluates all operators client-side for GetAsync / GetBatchAsync.

The Qdrant 4.2.0 text/configurable-hybrid paths also support Exists / NotExists and reject unsupported range/Like filters instead of skipping them.


VectorSearchResult

A single result from vector, text, or hybrid search. Score scales depend on the backend and search mode; configurable hybrid search uses normalized weighted RRF scores in [0, 1].

foreach (var result in results)
{
    Console.WriteLine($"Score: {result.Score:F4}");
    Console.WriteLine($"Content: {result.Record.Content}");
}

IVectorStore Contract

Full interface surface area:

public interface IVectorStore
{
    // Write
    Task UpsertAsync(VectorRecord record, CancellationToken ct = default);
    Task UpsertBatchAsync(IEnumerable<VectorRecord> records, CancellationToken ct = default);

    // Read — single
    Task<VectorRecord?> GetAsync(string id, VectorFilter? filter = null, CancellationToken ct = default);

    // Read — batch  (default: sequential GetAsync fallback)
    Task<IReadOnlyList<VectorRecord>> GetBatchAsync(IEnumerable<string> ids, VectorFilter? filter = null, CancellationToken ct = default);

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

    // Search — hybrid dense + keyword  (default: throws NotSupportedException)
    Task<IReadOnlyList<VectorSearchResult>> HybridSearchAsync(float[] denseVector, string query, int topK = 5, VectorFilter? filter = null, CancellationToken ct = default);

    // Delete
    Task DeleteAsync(string id, VectorFilter? filter = null, CancellationToken ct = default);
    Task DeleteByFilterAsync(VectorFilter filter, CancellationToken ct = default);

    // Atomic replace  (default: DeleteByFilterAsync → UpsertBatchAsync, non-transactional)
    Task ReplaceByFilterAsync(VectorFilter filter, IReadOnlyList<VectorRecord> records, CancellationToken ct = default);

    // Count  (default: throws NotSupportedException)
    Task<long> CountAsync(VectorFilter? filter = null, CancellationToken ct = default);

    // Connectivity
    Task VerifyConnectionAsync(CancellationToken ct = default);
}

Default implementations

Method Default behavior
HybridSearchAsync Throws NotSupportedException
GetBatchAsync Sequential loop over GetAsync
ReplaceByFilterAsync DeleteByFilterAsync → UpsertBatchAsync (non-transactional)
CountAsync Throws NotSupportedException
VerifyConnectionAsync Task.CompletedTask (no-op)

Concrete stores override these defaults where a more efficient or transactional implementation is available.


Optional store diagnostics

Mythosia.VectorDb.IVectorStoreDiagnostics is an optional capability implemented alongside IVectorStore. It exposes stored data for inspection; it does not embed text, split documents, explain retrieval decisions, or add required methods to IVectorStore.

public interface IVectorStoreDiagnostics
{
    Task<IReadOnlyList<VectorRecord>> ListAllRecordsAsync(
        CancellationToken cancellationToken = default);

    Task<IReadOnlyList<VectorSearchResult>> ScoredListAsync(
        float[] queryVector, CancellationToken cancellationToken = default);
}

ListAllRecordsAsync returns all stored records. ScoredListAsync scores all records against a supplied vector, orders results by descending score, and applies no TopK limit. Neither method takes a metadata filter; do not treat these store-wide inspection methods as a tenant-scoped retrieval API. Score meaning depends on the implementation.

Check the capability before calling it:

if (store is IVectorStoreDiagnostics diagnostics)
{
    var records = await diagnostics.ListAllRecordsAsync(cancellationToken);
    var scores = await diagnostics.ScoredListAsync(queryVector, cancellationToken);
}

InMemory 4.3.0 implements this contract directly. RAG analysis (RagDiagnostics, diagnostic sessions, chunk previews, health checks and reports) remains in Mythosia.AI.Rag and consumes this capability. GetTotalRecordCount() is an InMemory convenience method, not a member of this interface.

The obsolete Mythosia.AI.Rag.IRagDiagnosticsStore remains in Mythosia.AI.Rag.Abstractions as a compatibility interface inheriting this contract. New implementations should depend on IVectorStoreDiagnostics; see the RAG abstractions migration notes.


Logical Isolation with Metadata

InNamespace() / InScope(), INamespaceContext, and IScopeContext were removed in v4.0.0. Set partition keys in Metadata and apply matching VectorFilter conditions on each operation:

IVectorStore store = new InMemoryVectorStore();  // or PostgresStore, QdrantStore, PineconeStore

// Set isolation via Metadata
record.Metadata["namespace"] = "docs";
record.Metadata["scope"] = "tenant-1";
await store.UpsertAsync(record);

// Filter via Where()
var filter = new VectorFilter()
    .Where("namespace", "docs")
    .Where("scope", "tenant-1");
var results = await store.SearchAsync(queryVector, topK: 5, filter: filter);

// Replace matching records (atomicity depends on the store)
var replaceFilter = new VectorFilter().Where("full_path", "/docs/file.md");
await store.ReplaceByFilterAsync(replaceFilter, newRecords);

// Delete by filter
await store.DeleteByFilterAsync(new VectorFilter().Where("namespace", "docs"));

// Count
long count = await store.CountAsync(new VectorFilter().Where("namespace", "docs"));

VectorFilter in Practice

Top-level conditions are AND-combined. MinScore is ignored by CountAsync and DeleteByFilterAsync.

// Exact match + isolation
var filter = new VectorFilter()
    .Where("storage_id", "abc")
    .Where("file_type", "pdf")
    .Where("namespace", "docs")
    .Where("scope", "tenant-1");

// Use directly
var results = await store.SearchAsync(queryVector, topK: 5, filter: filter);

// Multi-tenant permission pattern
var permFilter = new VectorFilter()
    .WhereIn("storage_id", allowedIds)
    .WhereLike("folder_path", "/shared/%");

// MinScore filtering
var highConf = new VectorFilter().Where("lang", "ko").WithMinScore(0.75);

Bm25Tokenizer

Static utility backed by Lucene.Net StandardAnalyzer. Used internally by Bm25Index (InMemory) and sparse vector builders (Qdrant, Pinecone).

using Mythosia.VectorDb;

var result = Bm25Tokenizer.Analyze("machine learning neural network");
// result.Tokens           → ["machine", "learning", "neural", "network"]
// result.TermFrequencies  → { "machine": 1, "learning": 1, ... }

Implementing a Custom IVectorStore

public class MyVectorStore : IVectorStore
{
    public Task UpsertAsync(VectorRecord record, CancellationToken ct = default)
        => /* store record */ Task.CompletedTask;

    public Task UpsertBatchAsync(IEnumerable<VectorRecord> records, CancellationToken ct = default)
        => /* store batch */ Task.CompletedTask;

    public Task<IReadOnlyList<VectorSearchResult>> SearchAsync(
        float[] queryVector, int topK = 5, VectorFilter? filter = null, CancellationToken ct = default)
        => /* cosine search */ Task.FromResult<IReadOnlyList<VectorSearchResult>>(Array.Empty<VectorSearchResult>());

    public Task<VectorRecord?> GetAsync(string id, VectorFilter? filter = null, CancellationToken ct = default)
        => /* lookup */ Task.FromResult<VectorRecord?>(null);

    public Task DeleteAsync(string id, VectorFilter? filter = null, CancellationToken ct = default)
        => /* delete */ Task.CompletedTask;

    public Task DeleteByFilterAsync(VectorFilter filter, CancellationToken ct = default)
        => /* filter delete */ Task.CompletedTask;

    // Optional overrides for efficiency / transactional guarantees:
    // public override Task<IReadOnlyList<VectorRecord>> GetBatchAsync(...)  { ... }
    // public override Task<IReadOnlyList<VectorSearchResult>> HybridSearchAsync(...) { ... }
    // public override Task ReplaceByFilterAsync(...) { ... }
    // public override Task<long> CountAsync(...) { ... }
    // public override Task VerifyConnectionAsync(...) { ... }
}

The custom store uses the same metadata and filter contracts:

IVectorStore store = new MyVectorStore();
record.Metadata["namespace"] = "docs";
await store.UpsertAsync(record);
var results = await store.SearchAsync(
    queryVector, filter: new VectorFilter().Where("namespace", "docs"));

A text-only query should not require a dummy dense vector, and hybrid settings should reach the backend unchanged. These optional contracts extend IVectorStore without adding requirements to existing store implementations:

  • ITextSearchStore.TextSearchAsync(query, topK, filter, cancellationToken) searches text without a dense query vector.
  • IConfigurableHybridSearchStore.HybridSearchAsync(denseVector, query, options, topK, filter, cancellationToken) accepts HybridSearchOptions for weighted RRF.
  • HybridSearchOptions defaults to VectorWeight = 0.5f, CandidateMultiplier = 2, RrfK = 60. Nonfinite weights, weights outside [0, 1], nonpositive candidate/smoothing settings and candidate-count overflow are rejected. Weight 0 disables dense search; weight 1 disables text search. Disabled legs do not inspect or validate their query input.

InMemory, PostgreSQL and Qdrant implement these contracts. Pinecone keeps its legacy native hybrid API; its classic dense-index adapter does not advertise text-only or configurable RRF support. A caller requesting unsupported capabilities must receive an error instead of having settings ignored. Pure text and vector results retain native scoring, while configurable hybrid scores use normalized weighted RRF; do not reuse thresholds blindly across modes.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.1 is compatible. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (6)

Showing the top 5 NuGet packages that depend on Mythosia.VectorDb.Abstractions:

Package Downloads
Mythosia.AI.Rag.Abstractions

Shared contracts for Mythosia RAG loading, splitting, embeddings, retrieval, reranking and context building. IRagRetriever and RagRetrievalRequest support text, lexical overrides, top-K, filters, progress and cancellation without requiring a query embedding. Optional IRetrievalEmbeddingProvider distinguishes document and query embeddings, while EmbeddingDocument snapshots document identity, title and ordered chunks. Retains IEmbeddingProvider and IRetrievalStrategy for existing implementations. Includes RagDocument, RagChunk and cloneable pipeline/query options. What's New in v6.5.0: Obsolete IRagDiagnosticsStore compatibility bridge to the independent IVectorStoreDiagnostics contract.

Mythosia.VectorDb.InMemory

In-memory vector and BM25 text search for Mythosia VectorDb. Provides cosine similarity, text-only retrieval, configurable normalized weighted RRF, metadata filtering, upsert/delete operations, batch retrieval and counts. Filters candidates before truncation, synchronizes record and keyword-index access, and returns independent record copies. Supports cancellation while waiting for access and between batch records; batch and document replacement operations do not provide transactional rollback. What's New in v4.3.0: Removes the RAG dependency and implements IVectorStoreDiagnostics in place of IRagDiagnosticsStore; concrete diagnostic methods remain available. This minor release intentionally includes a breaking interface migration.

Mythosia.VectorDb.Postgres

PostgreSQL and pgvector storage for Mythosia VectorDb with Cosine, Euclidean and InnerProduct similarity, jsonb metadata filters, text-only retrieval and configurable normalized weighted RRF. Uses persisted full-text indexing and optional pg_trgm word_similarity for keyword search, including CJK text. Provides batch retrieval, counts, HNSW/IVFFlat/NoIndex settings, connection verification and schema provisioning. What's New in v10.8.1: Mixed hybrid search honors configured HNSW EfSearch and IVFFlat Probes on the same connection and transaction as the search query.

Mythosia.VectorDb.Qdrant

Qdrant storage for Mythosia VectorDb with Cosine, Euclidean and Dot Product similarity, metadata filtering and automatic collection provisioning. Supports sparse-only text retrieval, configurable normalized weighted RRF and direct native sparse/dense hybrid fusion with server RRF or DBSF. Uses a single collection with metadata-based logical isolation and provides batch retrieval, counts and connection verification. What's New in v4.2.0: Sparse text and configurable hybrid search with literal metadata-key filtering.

Mythosia.VectorDb.Pinecone

Pinecone vector store implementation for Mythosia VectorDb. Uses Pinecone index as physical storage with optional PineconeOptions.Namespace for data isolation, metadata filtering, GetBatchAsync, CountAsync, and connection verification. What's New in v4.0.2: Updated hashing and JSON dependencies with current compatible vector contracts.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
4.2.0 171 10/3/2026
4.1.0 395 9/24/2026
4.0.1 1,443 4/4/2026
4.0.0 295 4/3/2026
3.0.1 323 4/1/2026
3.0.0 440 3/30/2026
2.4.0 322 3/29/2026
2.3.0 291 3/28/2026
2.2.0 355 3/22/2026
2.1.0 406 3/11/2026
2.0.0 320 3/6/2026
1.0.0 282 3/5/2026

v4.2.0: Adds optional IVectorStoreDiagnostics for all-record listing and similarity scoring without a RAG dependency. Existing IVectorStore implementations are unchanged and need not support diagnostics. Full notes: https://github.com/AJ-comp/Mythosia.AI/blob/main/src/vectordb/Mythosia.VectorDb.Abstractions/RELEASE_NOTES.md#v420