ChromaDotNet.VectorData 0.4.1

Prefix Reserved
There is a newer version of this package available.
See the version list below for details.
The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet add package ChromaDotNet.VectorData --version 0.4.1
                    
NuGet\Install-Package ChromaDotNet.VectorData -Version 0.4.1
                    
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="ChromaDotNet.VectorData" Version="0.4.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="ChromaDotNet.VectorData" Version="0.4.1" />
                    
Directory.Packages.props
<PackageReference Include="ChromaDotNet.VectorData" />
                    
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 ChromaDotNet.VectorData --version 0.4.1
                    
#r "nuget: ChromaDotNet.VectorData, 0.4.1"
                    
#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 ChromaDotNet.VectorData@0.4.1
                    
#: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=ChromaDotNet.VectorData&version=0.4.1
                    
Install as a Cake Addin
#tool nuget:?package=ChromaDotNet.VectorData&version=0.4.1
                    
Install as a Cake Tool

ChromaDotNet

ChromaDotNet.VectorData

A Chroma provider for Microsoft.Extensions.VectorData, built on ChromaDotNet.Client.

This is a community project. It is not affiliated with or endorsed by Chroma.

Website: chromadotnet.org

Quick start

  1. Run Chroma with Docker:
docker run -d --name chroma -p 8000:8000 chromadb/chroma:1.5.9
  1. Install the NuGet package:
dotnet add package ChromaDotNet.VectorData
  1. Store and search records:
using ChromaDB.Client;
using ChromaDB.VectorData;
using Microsoft.Extensions.VectorData;

using var httpClient = new HttpClient();
var client = new ChromaClient(new ChromaConfigurationOptions("http://localhost:8000"), httpClient);
using var vectorStore = new ChromaVectorStore(client, ownsClient: false);

var collection = vectorStore.GetCollection<string, Hotel>("hotels");
await collection.EnsureCollectionExistsAsync();

await collection.UpsertAsync(new Hotel { Id = "h1", Name = "Grand", Rating = 5, Embedding = new float[] { 0.1f, 0.2f, 0.3f, 0.4f } });

await foreach (var result in collection.SearchAsync(new float[] { 0.1f, 0.2f, 0.3f, 0.4f }, top: 3, new() { Filter = h => h.Rating >= 4 }))
{
    Console.WriteLine($"{result.Record.Name}: {result.Score}");
}

public sealed class Hotel
{
    [VectorStoreKey]
    public string Id { get; set; } = "";

    [VectorStoreData(IsFullTextIndexed = true)]
    public string? Name { get; set; }

    [VectorStoreData]
    public int Rating { get; set; }

    [VectorStoreVector(4)]
    public ReadOnlyMemory<float> Embedding { get; set; }
}

With dependency injection, the vector store takes the ChromaClient from the container. That can be the singleton that ChromaDotNet.Client.DependencyInjection registers, which gets its HttpClient from IHttpClientFactory:

// dotnet add package ChromaDotNet.Client.DependencyInjection
using ChromaDB.Client;
using ChromaDB.Client.DependencyInjection;

services.AddChromaClient(_ => new ChromaConfigurationOptions("http://localhost:8000"));
services.AddChromaVectorStore();

Or the vector store creates its own client from a connection string: a URI, or the endpoint, token, tenant and database of Chroma Cloud:

services.AddChromaVectorStore("http://localhost:8000");

services.AddChromaVectorStore("Endpoint=https://api.trychroma.com;Token=<api key>;Tenant=<tenant>;Database=<database>");

AddChromaCollection<TKey, TRecord>(name, …) registers one collection in the same two ways. AddKeyedChromaVectorStore and AddKeyedChromaCollection register them under a key.

With these registrations, the embedding generator is the EmbeddingGenerator set in ChromaVectorStoreOptions or ChromaCollectionOptions. If none is set, it is an IEmbeddingGenerator registered in the container.

Without dependency injection, ChromaVectorStore and ChromaCollection take a ChromaClient. With ownsClient: true, they dispose it.

GetService(typeof(ChromaClient)) on the vector store or on a collection returns the client it uses.

Chroma Cloud

Connect with the endpoint, the API key, and the tenant and the database shown in the Chroma Cloud dashboard. The client sends the API key in the X-Chroma-Token header.

Chroma Cloud reads and writes at most 300 records per request. On Chroma Cloud addresses, the client reads and writes in batches of 300 by itself. A search returns at most 300 results, counting both top and Skip.

Chroma Cloud also limits metadata and documents:

  • A record has at most 32 metadata keys.
  • A key has at most 36 bytes.
  • A value has at most 8,182 bytes.
  • A document has at most 16,384 bytes.

Each property with a value is a key, and so is the BM25 vector of a full-text indexed string property: see hybrid search below.

If the text of the property stored as the document is longer than 8,182 bytes, it is stored in the document only. Contains finds it, but == does not.

On Chroma Cloud, HybridSearchAsync searches with a vector and keywords together:

var results = collection.HybridSearchAsync(new float[] { 0.1f, 0.2f, 0.3f, 0.4f }, ["pool", "spa"], top: 5);

It fuses the ranks of two searches: the vector search, and a BM25 search of the keywords in a full-text indexed string property. The BM25 search needs a BM25 index on the text of the property. A BM25 index is a Chroma sparse vector index.

On Chroma Cloud, creating the collection creates a BM25 index for each full-text indexed string property, like Name in Hotel above. The client then computes the BM25 vectors of the records as it writes them. The index of the property stored as the document is on the documents, under the key document_bm25; the index of another property is under its storage name with _bm25 added. An index whose key would have more than 36 bytes is left out.

A collection answers IKeywordHybridSearchable from GetService only on Chroma Cloud, and only when it has a full-text indexed string property. The TextSearchStore of Semantic Kernel asks for this interface to choose hybrid search over vector search. AddChromaCollection registers the collection as IKeywordHybridSearchable<TRecord> in any case, so resolve it from the container only on Chroma Cloud.

The score of a hybrid result is the reciprocal rank fusion score (k = 60) of the two searches. Higher is better, and the score is well below 1. ScoreThreshold applies to it.

A collection created by another Chroma client, like the Python one, works too when it has a chroma_bm25 index on the text of the property. For the property stored as the document, the index goes on the documents.

A record without any of the keywords gets nothing from the BM25 search, as in a keyword search.

A single Chroma server has neither the Search API nor sparse vector indexes: there, the collection is created without BM25 indexes.

Supported

  • Keys: string and Guid.
  • One vector per record: ReadOnlyMemory<float>, Embedding<float> or float[], or any type with an embedding generator.
  • Data properties, stored as Chroma metadata:
    • string, int, long, double, float, bool, DateTime, DateTimeOffset and DateOnly (.NET 8 and later)
    • their nullable forms
    • arrays or List<T> of the non-nullable ones
  • Dates are stored as ISO 8601 strings. A DateTimeOffset is stored in UTC, so it comes back as the same instant with offset zero. A DateTime is stored with its Kind.
  • Targets .NET 10, .NET 8, .NET Standard 2.0 and .NET Framework 4.6.2. NativeAOT needs .NET 8 or later.
  • Distance functions: CosineSimilarity (the default), CosineDistance, DotProductSimilarity, NegativeDotProductSimilarity, EuclideanDistance and EuclideanSquaredDistance, with the HNSW index.
  • An existing collection must use the space of the distance function. A collection created by another Chroma client without a space uses l2. If the space differs, creating or searching the collection throws, rather than turning the distances of another space into scores.
  • Filters:
    • == and !=
    • <, <=, > and >= on numbers
    • &&, || and !
    • Contains over an inline list or an array property
    • Any with Contains over an inline list
  • Filters on the key: ==, and Contains over a list of keys, joined to the other conditions with &&. Chroma looks the records up by id.
  • Full-text: the only full-text indexed string property is also stored as the Chroma document. That is where other Chroma clients store their text.
    • Contains and !Contains on it filter the text of the document, joined to the other conditions with &&.
    • When a record has its text in the document only, the provider reads it into that property.
    • A null text deletes the document of a record that exists, and reads back as null. An empty text reads back as empty.
  • NativeAOT and trimming: the dynamic collection works without reflection. You get it from GetDynamicCollection with a VectorStoreCollectionDefinition. ChromaCollection<TKey, TRecord> maps the properties of the record type by reflection. AddChromaVectorStore and AddKeyedChromaVectorStore work with trimming and NativeAOT. AddChromaCollection and AddKeyedChromaCollection map a record type, so they are marked as incompatible. There, register the vector store and get the collection from it with GetDynamicCollection.

Limitations

  • Chroma metadata has no null values. A null property is not stored, and filtering on null is not supported.
  • Upserting a record that exists replaces it: a value that is now null, or an empty list, is deleted, and a null text deletes the document.
  • Chroma does not store empty lists. An empty array or list is not stored, and comes back as null.
  • GetAsync with a filter does not support ordering.
  • Comparisons work on numbers only. A negated comparison, like !(r.Rating > 3), is not supported on a nullable property: Chroma would leave out the records where the property is null.
  • A DateTime filter finds the same ticks with the same Kind.
  • Array properties need Chroma 1.5.0 or later.
  • Hybrid search needs Chroma Cloud.
  • Only one property can be the document. With more than one full-text indexed string property, none is.

In CI, the provider runs the Microsoft.Extensions.VectorData conformance tests against Chroma 1.5.0, 1.5.9 and the latest release. On Chroma Cloud, the tests are run by hand, hybrid search included, and they pass.

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 is compatible.  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 is compatible.  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 netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 is compatible.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  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

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
0.4.2 0 10/7/2026

0.4.1: This version needs ChromaDotNet.Client 2.10.2. On Chroma Cloud, a filter on the keys with a large top, like GetAsync(r => r.Key == "a", top: 1000), no longer goes over the quota of 300 records per request: the client asks for at most as many records as there are keys. All the releases: https://github.com/ChromaDotNet/ChromaDB.VectorData/releases