From 336a9b59e3aa8fc13acfa7348ea125a4c1471ca5 Mon Sep 17 00:00:00 2001 From: qi_dq <455274752@qq.com> Date: Thu, 3 Jul 2025 11:28:36 +0800 Subject: [PATCH 1/5] Add Filter to TextSearchProvider --- .../Data/TextSearchBehavior/TextSearchProvider.cs | 2 +- .../Data/TextSearchBehavior/TextSearchProviderOptions.cs | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs index 6d68ecd0cd45..7c23645f8b9c 100644 --- a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs +++ b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs @@ -75,7 +75,7 @@ public override async Task ModelInvokingAsync(ICollection + /// The filter expression to apply to the search query. + /// + public TextSearchFilter? Filter { get; init; } + /// /// Gets or sets the time at which the text search is performed. /// From 561cf926fd00f4ab0052761234fcbdacf6682c8d Mon Sep 17 00:00:00 2001 From: qi_dq <455274752@qq.com> Date: Thu, 3 Jul 2025 13:33:24 +0800 Subject: [PATCH 2/5] Adjust the SearchAsync support configuration Filter --- .../Data/TextSearchBehavior/TextSearchProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs index 7c23645f8b9c..6ee680d91826 100644 --- a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs +++ b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProvider.cs @@ -96,7 +96,7 @@ internal async Task SearchAsync(string userQuestion, CancellationToken c { var searchResults = await this._textSearch.GetTextSearchResultsAsync( userQuestion, - new() { Top = this.Options.Top }, + new() { Top = this.Options.Top, Filter = this.Options.Filter }, cancellationToken: cancellationToken).ConfigureAwait(false); var results = await searchResults.Results.ToListAsync(cancellationToken).ConfigureAwait(false); From 9131dedbb3aaf8ece6156c46d570223e17cb0e30 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=B3=E5=86=89?= <455274752@qq.com> Date: Fri, 4 Jul 2025 09:18:26 +0800 Subject: [PATCH 3/5] Update dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProviderOptions.cs Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> --- .../Data/TextSearchBehavior/TextSearchProviderOptions.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProviderOptions.cs b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProviderOptions.cs index 3b260e45544f..f6cd9008012b 100644 --- a/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProviderOptions.cs +++ b/dotnet/src/SemanticKernel.Core/Data/TextSearchBehavior/TextSearchProviderOptions.cs @@ -34,7 +34,7 @@ public int Top } /// - /// The filter expression to apply to the search query. + /// Gets or sets the filter expression to apply to the search query. /// public TextSearchFilter? Filter { get; init; } From 4ce7ae41339a853d3e3aae4db4f106431dac34b1 Mon Sep 17 00:00:00 2001 From: qi_dq <455274752@qq.com> Date: Fri, 4 Jul 2025 13:38:39 +0800 Subject: [PATCH 4/5] Adjust the tests for TextSearchProviderTests that add the Filter functionality --- .../Data/TextSearchProviderTests.cs | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs b/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs index 2aaa037265bc..e68e4ad3d8f6 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs @@ -263,4 +263,56 @@ public async Task ModelInvokingShouldUseOverrideContextFormatterIfProvidedAsync( // Assert Assert.Equal("Custom formatted context with 2 results.", result.Instructions); } + + [Fact] + public async Task SearchAsyncRespectsFilterOption() + { + // Arrange + var mockTextSearch = new Mock(); + var searchResults = new Mock>(); + var mockEnumerator = new Mock>(); + + // 模拟被过滤的结果 + var filteredResult = new TextSearchResult("Filtered Content") { Name = "FilteredDoc", Link = "http://example.com/filtered" }; + var results = new List { filteredResult }; + + mockEnumerator.SetupSequence(e => e.MoveNextAsync()) + .ReturnsAsync(true) + .ReturnsAsync(false); + + mockEnumerator.SetupSequence(e => e.Current) + .Returns(filteredResult); + + searchResults.Setup(r => r.GetAsyncEnumerator(It.IsAny())) + .Returns(mockEnumerator.Object); + + TextSearchFilter? capturedFilter = null; + mockTextSearch.Setup(ts => ts.GetTextSearchResultsAsync( + It.IsAny(), + It.IsAny(), + It.IsAny())) + .Callback((q, opts, ct) => + { + capturedFilter = opts?.Filter; + }) + .ReturnsAsync(new KernelSearchResults(searchResults.Object)); + + var filter = new TextSearchFilter().Equality("Name", "FilteredDoc"); + var options = new TextSearchProviderOptions + { + Filter = filter + }; + + var provider = new TextSearchProvider(mockTextSearch.Object, options: options); + + // Act + var result = await provider.SearchAsync("Sample user question?", CancellationToken.None); + + // Assert + Assert.Contains("Filtered Content", result); + Assert.Contains("SourceDocName: FilteredDoc", result); + Assert.Contains("SourceDocLink: http://example.com/filtered", result); + Assert.NotNull(capturedFilter); + Assert.Equal(filter, capturedFilter); + } } From fcf1307ba7e430ff18a80d1fd21880dbdcb9790d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=B7=B3=E5=86=89?= <455274752@qq.com> Date: Sat, 5 Jul 2025 21:12:46 +0800 Subject: [PATCH 5/5] Update dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs Translate into English Co-authored-by: westey <164392973+westey-m@users.noreply.github.com> --- .../SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs b/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs index e68e4ad3d8f6..28d37124a3c9 100644 --- a/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs +++ b/dotnet/src/SemanticKernel.UnitTests/Data/TextSearchProviderTests.cs @@ -272,7 +272,7 @@ public async Task SearchAsyncRespectsFilterOption() var searchResults = new Mock>(); var mockEnumerator = new Mock>(); - // 模拟被过滤的结果 + // Simulate the filtered results var filteredResult = new TextSearchResult("Filtered Content") { Name = "FilteredDoc", Link = "http://example.com/filtered" }; var results = new List { filteredResult };