Skip to content

Commit b33f63e

Browse files
committed
feat: Add generic ITextSearch<TRecord> demonstration to GettingStartedWithTextSearch sample
- Add SearchWithLinqFilteringAsync() method showing type-safe LINQ filtering patterns - Demonstrate compile-time safety benefits vs. legacy clause-based filtering - Provide educational console output explaining modernization benefits - Show conceptual examples for BingWebPage, GoogleWebPage, and VectorStore with generic interface usage - Cover all existing connectors present in the current samples (Bing, Google, VectorStore) - Maintain full backward compatibility with existing legacy examples - Future-proof design works independently and integrates with connector implementations Addresses #10456 - PR 6/6 sample modernization
1 parent b94f3f3 commit b33f63e

File tree

1 file changed

+102
-0
lines changed

1 file changed

+102
-0
lines changed

dotnet/samples/GettingStartedWithTextSearch/Step1_Web_Search.cs

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,4 +127,106 @@ public async Task SearchForTextSearchResultsAsync()
127127
Console.WriteLine($"Link: {result.Link}");
128128
}
129129
}
130+
131+
/// <summary>
132+
/// Show how to use the new generic <see cref="ITextSearch{TRecord}"/> interface with LINQ filtering for type-safe searches.
133+
/// This demonstrates the modernized text search functionality introduced in Issue #10456.
134+
/// </summary>
135+
/// <remarks>
136+
/// This example shows the intended pattern for the new generic interfaces.
137+
/// Currently demonstrates the concept using examples from the existing connectors in this sample suite:
138+
/// - BingTextSearch and GoogleTextSearch (this file)
139+
/// - VectorStoreTextSearch (Step4_Search_With_VectorStore.cs)
140+
/// </remarks>
141+
[Fact]
142+
public async Task SearchWithLinqFilteringAsync()
143+
{
144+
// This example demonstrates the NEW generic interface pattern with LINQ filtering
145+
// that provides compile-time type safety and IntelliSense support
146+
147+
Console.WriteLine("\n--- Type-Safe Search with Generic Interface and LINQ Filtering ---\n");
148+
Console.WriteLine("This demonstrates the modernized ITextSearch<TRecord> pattern from Issue #10456");
149+
Console.WriteLine("Key benefits:");
150+
Console.WriteLine("- Compile-time type safety (no runtime errors from property name typos)");
151+
Console.WriteLine("- IntelliSense support for filtering properties");
152+
Console.WriteLine("- LINQ expressions for complex filtering logic");
153+
Console.WriteLine("- Better developer experience with strongly-typed search results");
154+
Console.WriteLine();
155+
156+
Console.WriteLine("=== Connectors Available in This Sample Suite ===");
157+
Console.WriteLine();
158+
159+
Console.WriteLine("1. VectorStoreTextSearch<TRecord> (Step4_Search_With_VectorStore.cs)");
160+
Console.WriteLine(" ✅ Already implements ITextSearch<TRecord> with LINQ filtering:");
161+
Console.WriteLine(" var vectorSearch = new VectorStoreTextSearch<DataModel>(collection);");
162+
Console.WriteLine(" var options = new TextSearchOptions<DataModel>");
163+
Console.WriteLine(" {");
164+
Console.WriteLine(" Filter = record => record.Tag == \"Technology\" && record.Title.Contains(\"AI\")");
165+
Console.WriteLine(" };");
166+
Console.WriteLine(" var results = await vectorSearch.GetSearchResultsAsync(query, options);");
167+
Console.WriteLine();
168+
169+
if (this.UseBingSearch)
170+
{
171+
Console.WriteLine("2. BingTextSearch (this file - BingSearchAsync())");
172+
Console.WriteLine(" 📋 Pattern for future generic interface (once PR3 is merged):");
173+
Console.WriteLine(" var bingSearch = new BingTextSearch(apiKey);");
174+
Console.WriteLine(" var options = new TextSearchOptions<BingWebPage>");
175+
Console.WriteLine(" {");
176+
Console.WriteLine(" Top = 4,");
177+
Console.WriteLine(" Filter = page => page.Name.Contains(\"Microsoft\") && page.Snippet.Contains(\"AI\")");
178+
Console.WriteLine(" };");
179+
Console.WriteLine(" var results = await ((ITextSearch<BingWebPage>)bingSearch).GetSearchResultsAsync(query, options);");
180+
Console.WriteLine(" // Type-safe access: page.Name, page.Snippet, page.Url, page.DateLastCrawled");
181+
}
182+
else
183+
{
184+
Console.WriteLine("2. BingTextSearch (set UseBingSearch = true to see example)");
185+
}
186+
187+
Console.WriteLine();
188+
Console.WriteLine("3. GoogleTextSearch (this file - GoogleSearchAsync())");
189+
Console.WriteLine(" 📋 Pattern for future generic interface (once PR4 is merged):");
190+
Console.WriteLine(" var googleSearch = new GoogleTextSearch(searchEngineId, apiKey);");
191+
Console.WriteLine(" var options = new TextSearchOptions<GoogleWebPage>");
192+
Console.WriteLine(" {");
193+
Console.WriteLine(" Top = 4,");
194+
Console.WriteLine(" Filter = page => page.Title.Contains(\"AI\") && page.DisplayLink.EndsWith(\".com\")");
195+
Console.WriteLine(" };");
196+
Console.WriteLine(" var results = await ((ITextSearch<GoogleWebPage>)googleSearch).GetSearchResultsAsync(query, options);");
197+
Console.WriteLine(" // Type-safe access: page.Title, page.Snippet, page.DisplayLink, page.Link");
198+
Console.WriteLine();
199+
200+
Console.WriteLine("=== Key Technical Benefits ===");
201+
Console.WriteLine();
202+
Console.WriteLine("✅ Compile-time validation - no more runtime property name errors");
203+
Console.WriteLine("✅ IntelliSense support - IDE shows available properties for each connector");
204+
Console.WriteLine("✅ Type safety - strongly typed search results and filtering");
205+
Console.WriteLine("✅ LINQ expressions - familiar &&, ||, Contains(), StartsWith(), comparisons, etc.");
206+
Console.WriteLine("✅ 100% backward compatibility - existing ITextSearch code unchanged");
207+
Console.WriteLine();
208+
209+
Console.WriteLine("=== Example LINQ Filtering Patterns ===");
210+
Console.WriteLine();
211+
Console.WriteLine("// Bing: Filter web pages by content and metadata");
212+
Console.WriteLine("Filter = page => page.Name.Contains(\"Microsoft\") && page.DateLastCrawled > DateTime.Now.AddDays(-7)");
213+
Console.WriteLine();
214+
Console.WriteLine("// Google: Filter search results by domain and content");
215+
Console.WriteLine("Filter = result => result.Title.Contains(\"AI\") && result.DisplayLink.EndsWith(\".edu\")");
216+
Console.WriteLine();
217+
Console.WriteLine("// Vector Store: Filter custom record types with complex logic");
218+
Console.WriteLine("Filter = record => record.Category == \"Technology\" && record.Score > 0.75 && record.Tags.Any(t => t == \"AI\")");
219+
Console.WriteLine();
220+
221+
Console.WriteLine("The VectorStoreTextSearch already demonstrates this pattern in Step4!");
222+
Console.WriteLine("See Step4_Search_With_VectorStore.cs for working generic interface examples.");
223+
Console.WriteLine();
224+
Console.WriteLine("This modernization is part of the structured PR series for Issue #10456:");
225+
Console.WriteLine("PR1: Core generic interfaces ✅");
226+
Console.WriteLine("PR2: VectorStoreTextSearch implementation ✅");
227+
Console.WriteLine("PR3: BingTextSearch connector (future) 📋");
228+
Console.WriteLine("PR4: GoogleTextSearch connector (future) 📋");
229+
Console.WriteLine("PR5: TavilyTextSearch & BraveTextSearch connectors (future) 📋");
230+
Console.WriteLine("PR6: Samples and documentation (this PR) ✅");
231+
}
130232
}

0 commit comments

Comments
 (0)