Repository navigation
Releases: ChromaDotNet/ChromaDB.Client
Release list
2.11.0
ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection 2.11.0, released together.
New
ChromaConfigurationOptions.WithChromaCloud()says the server is Chroma Cloud behind a proxy or another address, for the rules of Chroma Cloud.
Changes of behavior
- A record without metadata keys comes back with an empty
Metadata, not null, when the read includes the metadatas. AddAsync,UpdateAsyncandUpsertAsyncthrow anArgumentExceptionfor a metadata without keys and for a list of values of more than one type, as the Python client does.GetAsyncthrows anArgumentOutOfRangeExceptionfor a negative limit or offset, and returns no record for a limit of 0 without a request.- A write that fails after some of its batches went says how many records went, and a collection client made by name does not run it again.
- With
deleteRecordsFirst, records that the server returns after their delete make the client throw aChromaExceptionand keep the collection. ChromaQuery.NResultsrejects a negative number.
Fixes
- An id condition sends each id once.
CreateCollectionAsyncandGetOrCreateCollectionAsyncreject the names.and...- A connection string takes
httpandhttpsendpoints only. - The weight of the text in
ChromaRank.HybridRrfnever goes below 0. AddKeyedChromaClientgives each key its ownHttpClient, and a null key throws anArgumentNullException.
NuGet: https://www.nuget.org/packages/ChromaDotNet.Client/2.11.0 and https://www.nuget.org/packages/ChromaDotNet.Client.DependencyInjection/2.11.0
2.10.3
ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection 2.10.3, released together.
AddAsync,UpdateAsyncandUpsertAsyncthrow anArgumentExceptionbefore any request when the embeddings, metadatas, documents or URIs are not as many as the ids, or an embedding has NaN or an infinity, also when the embeddings go as base64.DeleteAsyncwith an empty list of ids and no filters throws anArgumentException.GetAsyncwith more ids than the batch size returns an id given twice once.- On Chroma 0.x a collection without a space reports
L2, the default of Chroma. - docs/COMPATIBILITY.md numbers the known defects of the servers, and the code that works around one names it.
NuGet: https://www.nuget.org/packages/ChromaDotNet.Client/2.10.3 and https://www.nuget.org/packages/ChromaDotNet.Client.DependencyInjection/2.10.3
2.10.2
ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection 2.10.2, released together. The client has the same code as 2.10.1: GetAsync with ids sends a limit of at most the number of the ids, within the quota of 300 of Chroma Cloud.
NuGet: https://www.nuget.org/packages/ChromaDotNet.Client/2.10.2 and https://www.nuget.org/packages/ChromaDotNet.Client.DependencyInjection/2.10.2
2.10.1
GetAsync with ids sends a limit of at most the number of the ids: a larger one, like 1000, went over the quota of 300 of Chroma Cloud, which rejected the request also for a few ids.
NuGet: https://www.nuget.org/packages/ChromaDotNet.Client/2.10.1
2.10.0
Minor release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection: what an integration like Microsoft.Extensions.VectorData needs, done in the client.
dotnet add package ChromaDotNet.Client
Added
- Collections by name:
GetCollectionClient(name)follows the collection with that name, also after it is created again elsewhere.DeleteCollectionIfExistsAsync. - Updates and upserts: a null value or an empty list deletes the key, with the sparse vectors of its text.
ChromaRecords.NullDocumentsDeletedeletes the documents.WithDocumentCopyKey(key)copies each document into a metadata key, for awherefilter on the whole text. - Filters:
ChromaWhereOperator.Not,AllandNone, andChromaWhereDocumentOperator.Not.ChromaWhereOperatoralso filters ids and documents. - BM25:
ChromaCollectionSchema.WithBm25Index(sourceKey),FindBm25IndexAsync, andChromaRank.HybridRrffor hybrid search on Chroma Cloud. - Also:
ChromaQuery.OffsetandExpectedSpace,ChromaMetadataConvert,ChromaCloudQuotas.
Changed
InandNotInwithout values no longer throw anArgumentException: they areNoneandAll.GetOrCreateCollectionAsyncthrows when the collection exists with another space.- A query whose ids include some without a record leaves them out, as Chroma Cloud does, instead of failing on Chroma 1.x.
Tested
The whole suite on Chroma 1.5.9, 1.0.0, 0.6.3, 0.4.23 and Chroma Cloud, with the .NET 8 and .NET Standard 2.0 builds. The CI runs it against Chroma 0.4.10 to latest. See the compatibility table.
v2.9.2
Patch release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection. Package validation against 2.9.1 finds no breaking change, and there is no new public API.
dotnet add package ChromaDotNet.Client
Fixed
- Floats that Chroma cannot write. Chroma 1.x sends
nullfor an embedding beyond the range of a float in acosinecollection, and for the distance to it in anl2oripcollection.GetAsyncandQueryAsyncthrew aChromaExceptionfor the whole answer. Nownullreads asNaN, and the other records come back as they are, as with the Python client. A distance beyond the range of a float, which Chroma 0.6.3 sends, reads as an infinity with its sign.
Documentation
- Shorter texts in the README and in the migration guide from 1.x.
docs/COMPATIBILITY.md: the null embeddings and distances of Chroma 1.x, and-0.0in metadata, which Chroma 0.6.3, 1.0.0 and 1.5.9 return as0.0.
v2.9.1
Patch release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection. Package validation against 2.9.0 finds no breaking change, and there is no new public API.
dotnet add package ChromaDotNet.Client
Fixed
- Buckets of
db.client.operation.duration: the histogram advises the boundaries of the OpenTelemetry semantic conventions, 0.001 to 10 seconds, which OpenTelemetry 1.10 and later apply. Before, it had the default boundaries, made for milliseconds, and P50, P90 and P99 were always 5 s in the Aspire dashboard. The net8.0 build now takes System.Diagnostics.DiagnosticSource 9.0.20. On the netstandard2.0 build, the one of applications on .NET Core 3.1 to 7, the application adds a view, which the README shows. - Chains of filters:
a & b & c, or a chain built in a loop, goes as one$andlist, as the Python client writes it, for the filters on the metadata, on the documents and in the Search API. Before, a chain of 32 filters threw aJsonExceptionabout an object cycle. - Very long chains: a single Chroma server turns a list of filters into an SQLite expression as deep as the list; Chroma 1.5.9 answers 500 beyond 987 to 994 filters in one list, and crashes from about 4,400. The client counts that depth, and beyond 900 splits each long list into lists with the same meaning: Chroma 1.0.0, 1.0.21 and 1.5.9 then take 4,000 filters and stay up with more.
- A null value in
AddAsync: it throws anArgumentExceptionbefore the request. Chroma 0.x would drop the key without an error, and 1.x rejects the request. InUpdateAsyncandUpsertAsynca null deletes the key, as before.
Documentation
- Known defects of the servers, in
docs/COMPATIBILITY.md, each reproduced without the client:$containsreading_and%as wildcards up to 1.0.12;- the text after a NUL character;
- floats truncated against int metadata, doubles read with an error in the last digit, and embeddings of a cosine collection read back different in the last bit, on 1.x;
- wrong query results under concurrent writes on 0.4.24 and 0.6.3;
- the limits of long filters.
- Chroma Cloud takes at most 8 predicates in a filter, the default quota of a tenant.
- Null values and
Metadata: how to delete a key with a null value, and that a record without keys comes back withMetadatanull.
Whole doubles already stored
Whole doubles that an earlier version of the client wrote as 2 instead of 2.0 stay integers in Chroma: on those records LessThan("d", 2.2) does not find d = 2 until they are written again.
v2.9.0
Minor release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection: the settings of a new collection, the indexes of a schema, and numbers and texts that reach the server as written.
dotnet add package ChromaDotNet.Client
New
-
The settings of a new collection, in
ChromaCollectionDefinition.Configuration:Hnsw, the index of a single Chroma server:EfConstruction,EfSearch,MaxNeighbors,ResizeFactor,SyncThreshold,BatchSizeandNumThreads;Spann, the index of Chroma Cloud, also with the settings that Chroma takes only in a schema;EmbeddingFunction, the embedding function the collection declares, whichModifyConfigurationAsynccan now change too.
The client sends each setting where Chroma applies it: the HNSW settings as the
hnsw:metadata, the SPANN settings and the embedding function in theconfigurationof the request, and all of them in the schema when there is one.HnswandSpanntogether throw anArgumentException, and a server that ignores the settings of the other index gives aChromaException. -
The indexes of the values in a schema, as
create_indexanddelete_indexof the Python client:WithIndexandWithoutIndexwith aChromaSchemaIndex, for one metadata key or for all of them, and for the full-text search index of the documents. -
On Chroma Cloud:
ChromaSparseIndexAlgorithm.MaxScorefor a sparse vector index, read back inChromaSparseVectorIndex.Algorithm, and a customer-managed key of Google Cloud KMS,WithGcpCmek. -
ChromaCollection.Dimension,VersionandLogPosition, as the server reports them.
Fixed
- Numbers:
- Doubles and floats go with the fewest digits that read back as them, the same on every build, and whole ones as floats (
2.0, not2). Before, Chroma stored a whole double as an integer, andChromaWhereOperator.In("k", 0.0, 2.25)went as[0, 2.25], which Chroma rejects. - The HNSW settings that Chroma takes only as integers,
hnsw:M,hnsw:construction_ef,hnsw:search_ef,hnsw:num_threads,hnsw:batch_sizeandhnsw:sync_threshold, go as integers also when the metadata has a wholedouble. Another number there throws anArgumentException, where Chroma would answer 400. - On .NET Framework, the doubles of the answers are read right and
-0.0keeps its sign.
- Doubles and floats go with the fewest digits that read back as them, the same on every build, and whole ones as floats (
- What a server would store changed or drop throws an
ArgumentExceptionbefore the request:- a text with a lone half of a surrogate pair;
- a
ulongabovelong.MaxValue; - an empty list in the metadata of a record, or any list in the metadata of a collection;
- a name that the path of a URL drops, like
..; - an HNSW index with fewer than 2 neighbors, on which Chroma 1.5.9 crashes or misses the nearest records.
- .NET 6 and 7: the netstandard2.0 build takes the 8.0 packages of System.Text.Json and System.Diagnostics.DiagnosticSource, as in 2.7.1, so these applications build with no warnings.
Packages
- The ChromaDotNet icon, and the
vector-databasetag. - The README has a section on collections and records.
v2.8.0
Minor release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection: hybrid search computed by the client, large reads and writes handled for you, Chroma Cloud by connection string, traces and metrics, and an API aligned with the .NET conventions.
dotnet add package ChromaDotNet.Client
New
- Hybrid search, as the Python client of Chroma does it:
AddAsync,UpdateAsyncandUpsertAsynccompute the BM25 vectors of thechroma_bm25indexes of the schema, from the document or from a metadata key;ChromaRank.SparseKnn(text, key)takes a text, whichSearchAsyncturns into a sparse vector;ChromaSparseVectorIndex.Bm25Functionis theChromaBm25with the settings of the schema, also for a collection created by Python.
- A collection with a schema keeps its space. The space goes in the schema, as the Python client writes it: Chroma Cloud rejects the space as a configuration together with a schema.
- Large reads and writes, by default:
- writes go in batches of the
max_batch_sizeof the server, andGetAsyncreads in pages; - on Chroma Cloud, 300 records at a time, its quota;
- when a server rejects a batch beyond its quota of records, the client sends it again in batches of that quota.
- writes go in batches of the
- Chroma Cloud by connection string:
ChromaConfigurationOptions.FromConnectionString("Endpoint=...;Token=...;Tenant=...;Database=..."). - Traces and metrics with OpenTelemetry:
AddSource(ChromaTelemetry.ActivitySourceName)andAddMeter(ChromaTelemetry.MeterName). A span for each operation, with the attributes of the semantic conventions for database clients, and its duration indb.client.operation.duration. - Mocks in tests: the members of
ChromaClientandChromaCollectionClientare virtual, and a protected constructor makes a client without a server, as in the Azure SDKs. QueryAsyncwith ids, with one or more query embeddings.- .NET Framework 4.6.2: a build of its own, which runs next to OpenTelemetry without binding redirects.
- Dependency injection:
IServiceProvider.CreateChromaClient(options, httpClientName)makes the client thatAddChromaClientregisters, for an integration with anHttpClientname of its own. - Documentation: every parameter and result of the public API, for IntelliSense;
ChromaCollectionSchema.ToString()gives the JSON of a schema.
Aligned with the .NET conventions
2.8.0 brings the API in line with the .NET design guidelines. What to change in the code:
| Change | What to do |
|---|---|
Asynchronous methods end in Async |
GetOrCreateCollection → GetOrCreateCollectionAsync, Add → AddAsync, Query → QueryAsync, and so on |
| Read-only lists | Parameters, results and models are IReadOnlyList<T>: a List<T> or a collection expression still goes in |
| Read-only dictionaries | Metadata are IReadOnlyDictionary<string, object>: write them new Dictionary<string, object> { ["key"] = value } |
| One embedding, one URI per record | ChromaCollectionEntry and ChromaCollectionQueryEntry have Embedding and Uri; Data is gone, as no Chroma server fills it |
| Parameters named as the properties | new ChromaConfigurationOptions(uri, tenant: ..., database: ...) |
| Metadata values read as written | Strings stay strings and lists are List<object>; WithMetadataValues(ChromaMetadataValues.Inferred) reads them as before |
| Batches and pages by default | WithBatchSplitting(false) sends a write in one request |
ChromaException for the failures of a request |
Network errors, answers that are not the expected JSON and timeouts; other exceptions, like an assembly that does not load, go as they are |
AddChromaClient and AddKeyedChromaClient return the services |
Code that ignores the result compiles as before |
| One type for each filter | ChromaWhereOperator and ChromaWhereDocumentOperator, the types the methods take; ChromaWhere and ChromaWhereDocument are gone |
v2.7.1
Patch release of ChromaDotNet.Client and ChromaDotNet.Client.DependencyInjection: only the metadata of the packages. The code is the one of 2.7.0, and package validation against 2.7.0 finds no breaking change.
dotnet add package ChromaDotNet.Client
- Package descriptions: both packages say that the project is a community project, not affiliated with Chroma, and have the
chroma-cloudtag. - Releases only on NuGet: NuGet gets only the version tags. The previews built from
mainare no longer published there, and the earlier ones are unlisted.