Skip to content

Commit b071168

Browse files
.Net: Fix milvus search metric type bug. (#7063)
### Motivation and Context <!-- Thank you for your contribution to the semantic-kernel repo! Please help reviewers and future users, providing the following information: 1. Why is this change required? 2. What problem does it solve? 3. What scenario does it contribute to? 4. If it fixes an open issue, please link to the issue here. --> The `metricType` parameter in the `SearchAsync` method of the Milvus connector is incorrect. It will always use the `SimilarityMetricType.Ip` for searching. ### Description <!-- Describe your changes, the overall approach, the underlying design. These notes will help understanding how your code works. Thanks! --> The current code hard-codes the milvus search metric type to `SimilarityMetricType.Ip`, which causes the issue where even if the Metric type is specified as `SimilarityMetricType.Cosine` when creating the `MilvusMemoryStore`, `SimilarityMetricType.IP` is still used during the search. Issue: [#7062](#7062) ### Contribution Checklist <!-- Before submitting this PR, please make sure: --> - [X] The code builds clean without any errors or warnings - [X] The PR follows the [SK Contribution Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md) and the [pre-submission formatting script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts) raises no violations - [X] All unit tests pass, and I have added new tests where possible - [X] I didn't break anyone 😄 --------- Co-authored-by: Roger Barreto <[email protected]>
1 parent b85e7ae commit b071168

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

dotnet/src/Connectors/Connectors.Memory.Milvus/MilvusMemoryStore.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ public Task RemoveBatchAsync(string collectionName, IEnumerable<string> keys, Ca
446446
MilvusCollection collection = this.Client.GetCollection(collectionName);
447447

448448
SearchResults results = await collection
449-
.SearchAsync(EmbeddingFieldName, [embedding], SimilarityMetricType.Ip, limit, this._searchParameters, cancellationToken)
449+
.SearchAsync(EmbeddingFieldName, [embedding], this._metricType, limit, this._searchParameters, cancellationToken)
450450
.ConfigureAwait(false);
451451

452452
IReadOnlyList<string> ids = results.Ids.StringIds!;

dotnet/src/IntegrationTests/Connectors/Memory/Milvus/MilvusMemoryStoreTests.cs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,45 @@ public async Task GetNearestMatchesAsync(bool withEmbeddings)
220220
});
221221
}
222222

223+
[Theory]
224+
[InlineData(true)]
225+
[InlineData(false)]
226+
public async Task GetNearestMatchesWithMetricTypeAsync(bool withEmbeddings)
227+
{
228+
//Create collection with default, Ip metric
229+
await this.Store.CreateCollectionAsync(CollectionName);
230+
await this.InsertSampleDataAsync();
231+
await this.Store.Client.FlushAsync([CollectionName]);
232+
233+
//Search with Ip metric, run correctly
234+
List<(MemoryRecord Record, double SimilarityScore)> ipResults =
235+
this.Store.GetNearestMatchesAsync(CollectionName, new[] { 5f, 6f, 7f, 8f, 9f }, limit: 2, withEmbeddings: withEmbeddings).ToEnumerable().ToList();
236+
237+
Assert.All(ipResults, t => Assert.True(t.SimilarityScore > 0));
238+
239+
//Set the store to Cosine metric, without recreate collection
240+
this.Store = new(this._milvusFixture.Host, vectorSize: 5, port: this._milvusFixture.Port, metricType: SimilarityMetricType.Cosine, consistencyLevel: ConsistencyLevel.Strong);
241+
242+
//An exception will be thrown here, the exception message includes "metric type not match"
243+
MilvusException milvusException = Assert.Throws<MilvusException>(() => this.Store.GetNearestMatchesAsync(CollectionName, new[] { 5f, 6f, 7f, 8f, 9f }, limit: 2, withEmbeddings: withEmbeddings).ToEnumerable().ToList());
244+
245+
Assert.NotNull(milvusException);
246+
247+
Assert.Contains("metric type not match", milvusException.Message);
248+
249+
//Recreate collection with Cosine metric
250+
await this.Store.DeleteCollectionAsync(CollectionName);
251+
await this.Store.CreateCollectionAsync(CollectionName);
252+
await this.InsertSampleDataAsync();
253+
await this.Store.Client.FlushAsync([CollectionName]);
254+
255+
//Search with Ip metric, run correctly
256+
List<(MemoryRecord Record, double SimilarityScore)> cosineResults =
257+
this.Store.GetNearestMatchesAsync(CollectionName, new[] { 5f, 6f, 7f, 8f, 9f }, limit: 2, withEmbeddings: withEmbeddings).ToEnumerable().ToList();
258+
259+
Assert.All(cosineResults, t => Assert.True(t.SimilarityScore > 0));
260+
}
261+
223262
[Fact]
224263
public async Task GetNearestMatchesWithMinRelevanceScoreAsync()
225264
{

0 commit comments

Comments
 (0)