diff --git a/VectorSearchApp/Models/AddressEmbedding.cs b/VectorSearchApp/Models/AddressEmbedding.cs index dc7a059..66ba05a 100644 --- a/VectorSearchApp/Models/AddressEmbedding.cs +++ b/VectorSearchApp/Models/AddressEmbedding.cs @@ -5,4 +5,5 @@ public class AddressEmbedding public Guid Id { get; set; } public string FullAddress { get; set; } = string.Empty; public float[] Vector { get; set; } = Array.Empty(); + public float Score { get; set; } } \ No newline at end of file diff --git a/VectorSearchApp/Program.cs b/VectorSearchApp/Program.cs index 8364fa0..9b72bc9 100644 --- a/VectorSearchApp/Program.cs +++ b/VectorSearchApp/Program.cs @@ -156,13 +156,29 @@ async Task SearchAddressesAsync(IEmbeddingService embeddingService, IQdrantServi return; } + Console.Write("Enter similarity threshold (0.0-1.0, lower = stricter, press Enter for 0.7): "); + var thresholdInput = Console.ReadLine()?.Trim(); + float threshold = 0.7f; + if (!string.IsNullOrEmpty(thresholdInput) && float.TryParse(thresholdInput, out var parsedThreshold)) + { + threshold = Math.Clamp(parsedThreshold, 0f, 1f); + } + + Console.Write("Enter max results to return (press Enter for 5, or '2' for top 2 most similar): "); + var limitInput = Console.ReadLine()?.Trim(); + int limit = 5; + if (!string.IsNullOrEmpty(limitInput) && int.TryParse(limitInput, out var parsedLimit)) + { + limit = Math.Max(1, parsedLimit); + } + Console.WriteLine("Generating query embedding..."); try { var queryEmbedding = await embeddingService.GenerateEmbeddingAsync(query); - Console.WriteLine($"Searching for similar addresses..."); + Console.WriteLine($"Searching for similar addresses (threshold: {threshold:F2}, max results: {limit})..."); - var results = await qdrantService.SearchSimilarAddressesAsync(queryEmbedding, limit: 5); + var results = await qdrantService.SearchSimilarAddressesAsync(queryEmbedding, limit: limit, scoreThreshold: threshold); if (results.Count == 0) { @@ -173,7 +189,7 @@ async Task SearchAddressesAsync(IEmbeddingService embeddingService, IQdrantServi Console.WriteLine($"\nFound {results.Count} similar address(es):"); for (int i = 0; i < results.Count; i++) { - Console.WriteLine($" {i + 1}. {results[i].FullAddress}"); + Console.WriteLine($" {i + 1}. {results[i].FullAddress} (Score: {results[i].Score:F4})"); } } catch (Exception ex) diff --git a/VectorSearchApp/Services/QdrantService.cs b/VectorSearchApp/Services/QdrantService.cs index ac94fa0..d257a7f 100644 --- a/VectorSearchApp/Services/QdrantService.cs +++ b/VectorSearchApp/Services/QdrantService.cs @@ -9,7 +9,7 @@ public interface IQdrantService { Task InitializeCollectionAsync(CancellationToken cancellationToken = default); Task StoreAddressAsync(Address address, float[] embedding, CancellationToken cancellationToken = default); - Task> SearchSimilarAddressesAsync(float[] queryEmbedding, int limit = 5, CancellationToken cancellationToken = default); + Task> SearchSimilarAddressesAsync(float[] queryEmbedding, int limit = 5, float scoreThreshold = 0.0f, CancellationToken cancellationToken = default); } public class QdrantService : IQdrantService @@ -55,15 +55,16 @@ public class QdrantService : IQdrantService await _client.UpsertAsync(_collectionName, new[] { point }, cancellationToken: cancellationToken); } - public async Task> SearchSimilarAddressesAsync(float[] queryEmbedding, int limit = 5, CancellationToken cancellationToken = default) + public async Task> SearchSimilarAddressesAsync(float[] queryEmbedding, int limit = 5, float scoreThreshold = 0.0f, CancellationToken cancellationToken = default) { - var results = await _client.SearchAsync(_collectionName, queryEmbedding, limit: (ulong)limit, cancellationToken: cancellationToken); + var results = await _client.SearchAsync(_collectionName, queryEmbedding, limit: (ulong)limit, scoreThreshold: scoreThreshold, cancellationToken: cancellationToken); return results.Select(r => new AddressEmbedding { Id = Guid.Parse(r.Id.Uuid), FullAddress = r.Payload["address"].StringValue, - Vector = Array.Empty() + Vector = Array.Empty(), + Score = r.Score }).ToList(); } } \ No newline at end of file