Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions CommunityToolkit.AI.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
<Folder Name="/MEVD/src/">
<File Path="MEVD/src/Directory.Build.props" />
<Project Path="MEVD/src/AzureAISearch/AzureAISearch.csproj" />
<Project Path="MEVD/src/CosmosNoSql/CosmosNoSql.csproj" />
<Project Path="MEVD/src/CosmosMongoDB/CosmosMongoDB.csproj" />
<Project Path="MEVD/src/InMemory/InMemory.csproj" />
<Project Path="MEVD/src/PgVector/PgVector.csproj" />
Expand All @@ -22,6 +23,8 @@
<Folder Name="/MEVD/test/">
<Project Path="MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj" />
<Project Path="MEVD/test/AzureAISearch.ConformanceTests/AzureAISearch.ConformanceTests.csproj" />
<Project Path="MEVD/test/CosmosNoSql.UnitTests/CosmosNoSql.UnitTests.csproj" />
<Project Path="MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSql.ConformanceTests.csproj" />
<Project Path="MEVD/test/CosmosMongoDB.UnitTests/CosmosMongoDB.UnitTests.csproj" />
<Project Path="MEVD/test/CosmosMongoDB.ConformanceTests/CosmosMongoDB.ConformanceTests.csproj" />
<Project Path="MEVD/test/InMemory.UnitTests/InMemory.UnitTests.csproj" />
Expand Down
2 changes: 2 additions & 0 deletions Directory.Packages.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<PackageVersion Include="Microsoft.Extensions.VectorData.ConformanceTests" Version="10.5.2" />

<PackageVersion Include="Azure.Search.Documents" Version="11.7.0" />
<PackageVersion Include="Microsoft.Azure.Cosmos" Version="3.61.0" />
<PackageVersion Include="Microsoft.Data.SqlClient" Version="6.1.6" />
<PackageVersion Include="Microsoft.Data.Sqlite" Version="10.0.6" />
<PackageVersion Include="MongoDB.Driver" Version="3.7.1" />
Expand Down Expand Up @@ -45,6 +46,7 @@
<PackageVersion Include="Humanizer" Version="3.0.10" />
<PackageVersion Include="Moq" Version="4.20.72" />
<PackageVersion Include="Testcontainers" Version="4.11.0" />
<PackageVersion Include="Testcontainers.CosmosDb" Version="4.12.0" />
<PackageVersion Include="Testcontainers.MsSql" Version="4.12.0" />
<PackageVersion Include="Testcontainers.PostgreSql" Version="4.11.0" />
<PackageVersion Include="Testcontainers.Qdrant" Version="4.11.0" />
Expand Down
3 changes: 3 additions & 0 deletions MEVD/MEVD.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"projects":
[
"MEVD/src/AzureAISearch/AzureAISearch.csproj",
"MEVD/src/CosmosNoSql/CosmosNoSql.csproj",
"MEVD/src/CosmosMongoDB/CosmosMongoDB.csproj",
"MEVD/src/InMemory/InMemory.csproj",
"MEVD/src/Pinecone/Pinecone.csproj",
Expand All @@ -16,6 +17,8 @@

"MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj",
"MEVD/test/AzureAISearch.ConformanceTests/AzureAISearch.ConformanceTests.csproj",
"MEVD/test/CosmosNoSql.UnitTests/CosmosNoSql.UnitTests.csproj",
"MEVD/test/CosmosNoSql.ConformanceTests/CosmosNoSql.ConformanceTests.csproj",
"MEVD/test/CosmosMongoDB.UnitTests/CosmosMongoDB.UnitTests.csproj",
"MEVD/test/CosmosMongoDB.ConformanceTests/CosmosMongoDB.ConformanceTests.csproj",
"MEVD/test/InMemory.UnitTests/InMemory.UnitTests.csproj",
Expand Down
2 changes: 2 additions & 0 deletions MEVD/src/CosmosNoSql/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
97 changes: 97 additions & 0 deletions MEVD/src/CosmosNoSql/ByteArrayJsonConverter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Collections.Generic;
using System.Text.Json;
using System.Text.Json.Serialization;

namespace CommunityToolkit.VectorData.CosmosNoSql;

/// <summary>
/// A JSON converter for byte arrays that serializes them as JSON arrays of numbers
/// instead of base64-encoded strings.
/// </summary>
/// <remarks>
/// This is needed because Cosmos DB's VectorDistance function requires vectors to be arrays of numbers,
/// not base64-encoded strings.
/// </remarks>
internal sealed class ByteArrayJsonConverter : JsonConverter<byte[]>
{
/// <inheritdoc/>
public override byte[] Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Support reading both base64 strings (for backward compatibility) and number arrays
if (reader.TokenType == JsonTokenType.String)
{
return reader.GetBytesFromBase64();
}

if (reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException($"Expected StartArray or String token, got {reader.TokenType}");
}

var list = new List<byte>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
list.Add(reader.GetByte());
}
return list.ToArray();
}

/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, byte[] value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var b in value)
{
writer.WriteNumberValue(b);
}
writer.WriteEndArray();
}
}

/// <summary>
/// A JSON converter for <see cref="ReadOnlyMemory{T}"/> of byte that serializes as JSON arrays of numbers
/// instead of base64-encoded strings.
/// </summary>
/// <remarks>
/// This is needed because Cosmos DB's VectorDistance function requires vectors to be arrays of numbers,
/// not base64-encoded strings.
/// </remarks>
internal sealed class ReadOnlyMemoryByteJsonConverter : JsonConverter<ReadOnlyMemory<byte>>
{
/// <inheritdoc/>
public override ReadOnlyMemory<byte> Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
{
// Support reading both base64 strings (for backward compatibility) and number arrays
if (reader.TokenType == JsonTokenType.String)
{
return new ReadOnlyMemory<byte>(reader.GetBytesFromBase64());
}

if (reader.TokenType != JsonTokenType.StartArray)
{
throw new JsonException($"Expected StartArray or String token, got {reader.TokenType}");
}

var list = new List<byte>();
while (reader.Read() && reader.TokenType != JsonTokenType.EndArray)
{
list.Add(reader.GetByte());
}
return new ReadOnlyMemory<byte>(list.ToArray());
}

/// <inheritdoc/>
public override void Write(Utf8JsonWriter writer, ReadOnlyMemory<byte> value, JsonSerializerOptions options)
{
writer.WriteStartArray();
foreach (var b in value.Span)
{
writer.WriteNumberValue(b);
}
writer.WriteEndArray();
}
}
43 changes: 43 additions & 0 deletions MEVD/src/CosmosNoSql/ClientWrapper.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

using System;
using System.Threading;
using Microsoft.Azure.Cosmos;

namespace CommunityToolkit.VectorData.CosmosNoSql;

internal sealed class ClientWrapper : IDisposable
{
private readonly bool _ownsClient;
private int _referenceCount = 1;

internal ClientWrapper(CosmosClient cosmosClient, bool ownsClient)
{
this.Client = cosmosClient;
this._ownsClient = ownsClient;
}

internal CosmosClient Client { get; }

internal ClientWrapper Share()
{
if (this._ownsClient)
{
Interlocked.Increment(ref this._referenceCount);
}

return this;
}

public void Dispose()
{
if (this._ownsClient)
{
if (Interlocked.Decrement(ref this._referenceCount) == 0)
{
this.Client.Dispose();
}
}
}
}
27 changes: 27 additions & 0 deletions MEVD/src/CosmosNoSql/CosmosNoSql.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Version>1.0.0-preview.1</Version>
<AssemblyName>CommunityToolkit.VectorData.CosmosNoSql</AssemblyName>
<RootNamespace>$(AssemblyName)</RootNamespace>
<TargetFrameworks>net10.0;net8.0;netstandard2.0;net462</TargetFrameworks>

<Title>Azure Cosmos DB for NoSQL provider for Microsoft.Extensions.VectorData</Title>
<Description>Azure Cosmos DB for NoSQL provider for Microsoft.Extensions.VectorData by the .NET Community Toolkit</Description>

<AzureCosmosDisableNewtonsoftJsonCheck>true</AzureCosmosDisableNewtonsoftJsonCheck>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Azure.Cosmos" />
<PackageReference Include="Microsoft.Extensions.AI.Abstractions" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" />
<PackageReference Include="System.Linq.AsyncEnumerable" />
<PackageReference Include="System.Text.Json" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="CommunityToolkit.VectorData.CosmosNoSql.UnitTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>

</Project>
Loading