diff --git a/MEVD/src/AzureAISearch/AzureAISearch.csproj b/MEVD/src/AzureAISearch/AzureAISearch.csproj index 63cf26c..980b870 100644 --- a/MEVD/src/AzureAISearch/AzureAISearch.csproj +++ b/MEVD/src/AzureAISearch/AzureAISearch.csproj @@ -1,6 +1,6 @@  - 1.0.0 + 1.0.1 CommunityToolkit.VectorData.AzureAISearch $(AssemblyName) net10.0;net8.0;netstandard2.0;net462 diff --git a/MEVD/src/AzureAISearch/AzureAISearchCollection.cs b/MEVD/src/AzureAISearch/AzureAISearchCollection.cs index e063aea..f458528 100644 --- a/MEVD/src/AzureAISearch/AzureAISearchCollection.cs +++ b/MEVD/src/AzureAISearch/AzureAISearchCollection.cs @@ -389,6 +389,11 @@ public override async IAsyncEnumerable> SearchAsync< Throw.IfLessThan(top, 1); options ??= s_defaultVectorSearchOptions; + if (options.IncludeVectors && _model.EmbeddingGenerationRequired) + { + throw new NotSupportedException(VectorDataStrings.IncludeVectorsNotSupportedWithEmbeddingGeneration); + } + var vectorProperty = _model.GetVectorPropertyOrSingle(options); var floatVector = await GetSearchVectorAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false); @@ -429,6 +434,11 @@ public async IAsyncEnumerable> HybridSearchAsync(new() { VectorProperty = options.VectorProperty }); var floatVector = await GetSearchVectorAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false); diff --git a/MEVD/src/Qdrant/Qdrant.csproj b/MEVD/src/Qdrant/Qdrant.csproj index 02fb8d4..0e61e28 100644 --- a/MEVD/src/Qdrant/Qdrant.csproj +++ b/MEVD/src/Qdrant/Qdrant.csproj @@ -1,7 +1,7 @@  - 1.0.0 + 1.0.1 CommunityToolkit.VectorData.Qdrant $(AssemblyName) net10.0;net8.0;netstandard2.0;net462 diff --git a/MEVD/src/Qdrant/QdrantCollection.cs b/MEVD/src/Qdrant/QdrantCollection.cs index f1aa9aa..0501341 100644 --- a/MEVD/src/Qdrant/QdrantCollection.cs +++ b/MEVD/src/Qdrant/QdrantCollection.cs @@ -669,6 +669,11 @@ public async IAsyncEnumerable> HybridSearchAsync(new() { VectorProperty = options.VectorProperty }); var vectorArray = await GetSearchVectorArrayAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false); var textDataProperty = _model.GetFullTextDataPropertyOrSingle(options.AdditionalProperty); diff --git a/MEVD/src/Weaviate/Weaviate.csproj b/MEVD/src/Weaviate/Weaviate.csproj index 1c8dffc..ef0fea6 100644 --- a/MEVD/src/Weaviate/Weaviate.csproj +++ b/MEVD/src/Weaviate/Weaviate.csproj @@ -2,7 +2,7 @@ - 1.0.0 + 1.0.1 CommunityToolkit.VectorData.Weaviate $(AssemblyName) net10.0;net8.0;netstandard2.0;net462 diff --git a/MEVD/src/Weaviate/WeaviateCollection.cs b/MEVD/src/Weaviate/WeaviateCollection.cs index 4599cd4..faa069d 100644 --- a/MEVD/src/Weaviate/WeaviateCollection.cs +++ b/MEVD/src/Weaviate/WeaviateCollection.cs @@ -410,6 +410,11 @@ public async IAsyncEnumerable> HybridSearchAsync(new() { VectorProperty = options.VectorProperty }); var vector = await GetSearchVectorAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false); var textDataProperty = _model.GetFullTextDataPropertyOrSingle(options.AdditionalProperty); diff --git a/MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj b/MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj index 61466ef..14107ae 100644 --- a/MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj +++ b/MEVD/test/AzureAISearch.UnitTests/AzureAISearch.UnitTests.csproj @@ -23,6 +23,7 @@ + diff --git a/MEVD/test/AzureAISearch.UnitTests/AzureAISearchHybridSearchEmbeddingGenerationTests.cs b/MEVD/test/AzureAISearch.UnitTests/AzureAISearchHybridSearchEmbeddingGenerationTests.cs new file mode 100644 index 0000000..5bd1980 --- /dev/null +++ b/MEVD/test/AzureAISearch.UnitTests/AzureAISearchHybridSearchEmbeddingGenerationTests.cs @@ -0,0 +1,50 @@ +// 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.Linq; +using System.Threading.Tasks; +using Azure.Search.Documents.Indexes; +using CommunityToolkit.VectorData.AzureAISearch; +using CommunityToolkit.VectorData.UnitTests; +using Microsoft.Extensions.VectorData; +using Moq; +using Xunit; + +namespace AzureAISearch.UnitTests; + +public sealed class AzureAISearchHybridSearchEmbeddingGenerationTests +{ + [Fact] + public async Task HybridSearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using AzureAISearchCollection collection = CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.HybridSearchAsync("search text", ["keyword"], top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + [Fact] + public async Task SearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using AzureAISearchCollection collection = CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.SearchAsync("search text", top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + private static AzureAISearchCollection CreateCollection() + => new(new Mock().Object, "collection", new() { EmbeddingGenerator = new FakeEmbeddingGenerator() }); + + public sealed class Record + { + [VectorStoreKey] + public string Id { get; set; } = string.Empty; + + [VectorStoreData(IsFullTextIndexed = true)] + public string Text { get; set; } = string.Empty; + + [VectorStoreVector(3)] + public string Embedding { get; set; } = string.Empty; + } +} diff --git a/MEVD/test/Qdrant.UnitTests/Qdrant.UnitTests.csproj b/MEVD/test/Qdrant.UnitTests/Qdrant.UnitTests.csproj index 863a56a..fc10072 100644 --- a/MEVD/test/Qdrant.UnitTests/Qdrant.UnitTests.csproj +++ b/MEVD/test/Qdrant.UnitTests/Qdrant.UnitTests.csproj @@ -26,6 +26,8 @@ Link="%(RecursiveDir)%(Filename)%(Extension)"/> + diff --git a/MEVD/test/Qdrant.UnitTests/QdrantHybridSearchEmbeddingGenerationTests.cs b/MEVD/test/Qdrant.UnitTests/QdrantHybridSearchEmbeddingGenerationTests.cs new file mode 100644 index 0000000..66fe5d6 --- /dev/null +++ b/MEVD/test/Qdrant.UnitTests/QdrantHybridSearchEmbeddingGenerationTests.cs @@ -0,0 +1,48 @@ +// 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.Linq; +using System.Threading.Tasks; +using CommunityToolkit.VectorData.UnitTests; +using Microsoft.Extensions.VectorData; +using Moq; +using Xunit; + +namespace CommunityToolkit.VectorData.Qdrant.UnitTests; + +public sealed class QdrantHybridSearchEmbeddingGenerationTests +{ + [Fact] + public async Task HybridSearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using QdrantCollection collection = CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.HybridSearchAsync("search text", ["keyword"], top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + [Fact] + public async Task SearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using QdrantCollection collection = CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.SearchAsync("search text", top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + private static QdrantCollection CreateCollection() + => new(() => new Mock(MockBehavior.Strict).Object, "collection", new() { EmbeddingGenerator = new FakeEmbeddingGenerator() }); + + public sealed class Record + { + [VectorStoreKey] + public ulong Id { get; set; } + + [VectorStoreData(IsFullTextIndexed = true)] + public string Text { get; set; } = string.Empty; + + [VectorStoreVector(3)] + public string Embedding { get; set; } = string.Empty; + } +} diff --git a/MEVD/test/Weaviate.UnitTests/Weaviate.UnitTests.csproj b/MEVD/test/Weaviate.UnitTests/Weaviate.UnitTests.csproj index b76eeb9..e8b4db2 100644 --- a/MEVD/test/Weaviate.UnitTests/Weaviate.UnitTests.csproj +++ b/MEVD/test/Weaviate.UnitTests/Weaviate.UnitTests.csproj @@ -24,6 +24,8 @@ + diff --git a/MEVD/test/Weaviate.UnitTests/WeaviateHybridSearchEmbeddingGenerationTests.cs b/MEVD/test/Weaviate.UnitTests/WeaviateHybridSearchEmbeddingGenerationTests.cs new file mode 100644 index 0000000..064aa94 --- /dev/null +++ b/MEVD/test/Weaviate.UnitTests/WeaviateHybridSearchEmbeddingGenerationTests.cs @@ -0,0 +1,63 @@ +// 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.Linq; +using System.Net.Http; +using System.Threading.Tasks; +using CommunityToolkit.VectorData.UnitTests; +using CommunityToolkit.VectorData.Weaviate; +using Microsoft.Extensions.VectorData; +using Xunit; + +namespace Weaviate.UnitTests; + +public sealed class WeaviateHybridSearchEmbeddingGenerationTests : IDisposable +{ + private readonly HttpMessageHandlerStub _messageHandlerStub = new(); + private readonly HttpClient _httpClient; + + public WeaviateHybridSearchEmbeddingGenerationTests() + { + this._httpClient = new(this._messageHandlerStub, false) { BaseAddress = new Uri("http://default-endpoint") }; + } + + public void Dispose() + { + this._httpClient.Dispose(); + this._messageHandlerStub.Dispose(); + } + + [Fact] + public async Task HybridSearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using WeaviateCollection collection = this.CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.HybridSearchAsync("search text", ["keyword"], top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + [Fact] + public async Task SearchAsync_WithIncludeVectorsAndEmbeddingGeneration_ThrowsNotSupported() + { + using WeaviateCollection collection = this.CreateCollection(); + + await Assert.ThrowsAsync(async () => + await collection.SearchAsync("search text", top: 3, new() { IncludeVectors = true }).ToListAsync()); + } + + private WeaviateCollection CreateCollection() + => new(this._httpClient, "Collection", new() { EmbeddingGenerator = new FakeEmbeddingGenerator() }); + + public sealed class Record + { + [VectorStoreKey] + public Guid Id { get; set; } + + [VectorStoreData(IsFullTextIndexed = true)] + public string Text { get; set; } = string.Empty; + + [VectorStoreVector(3)] + public string Embedding { get; set; } = string.Empty; + } +}