Skip to content

.Net MEVD: Modify ITextSearch to react to the new LINQ-based vector search filtering #10456

Closed

Description

@roji

ITextSearch accepts TextSearchOptions, which currently has an optional TextSearchFilter, which relies on the legacy non-LINQ vector search filtering feature. We need to modify it to use the new search interface. Mark Wallace (@markwallace-microsoft) let me know if/when you want to discuss ideas around this.

Activity

  1. added
    sk team issueA tag to denote issues that where created by the Semantic Kernel team (i.e., not the community)
    on Feb 10, 2025
  2. roji commented on Mar 5, 2025

    @roji
    MemberAuthor

    Mark Wallace (@markwallace-microsoft) just a reminder that this will need to happen at some point, not sure who's best for this...

  3. alzarei commented on Sep 20, 2025

    @alzarei
    Contributor

    Hi Shay Rojansky (@roji), Mark Wallace (@markwallace-microsoft), Please let me know if I am on the right track for understanding and tackling this

    Issue #10456 Analysis: Modernize ITextSearch to Use LINQ-Based Vector Search Filtering

    Context: What Are These Filtering Systems?

    Both filtering systems serve the same purpose: allowing developers to narrow down search results based on metadata or record properties before performing the actual search operation.

    Common Use Case: A knowledge base with documents containing metadata like category, department, confidentiality, and dateCreated. Developers need to filter searches like:

    • "Find 'API documentation' but only in technical documents"
    • "Search 'budget planning' but exclude confidential materials"

    The Two Approaches:

    • Legacy (TextSearchFilter): Clause-based with method chaining: filter.Equality("category", "technical")
    • Modern (LINQ): Type-safe expressions: doc => doc.Category == "technical" && doc.DateCreated > DateTime.Now.AddMonths(-6)

    The LINQ approach provides compile-time safety, IntelliSense support, and complex boolean logic—which is why vector stores moved to it.

    Overview

    This document analyzes GitHub Issue #10456 which requests modernizing the ITextSearch interface to use LINQ-based filtering instead of the legacy TextSearchFilter approach.

    Problem Statement

    Current State: Inconsistent Filtering APIs

    The Semantic Kernel .NET SDK currently has two different filtering systems:

    1. Legacy Text Search Filtering (used by ITextSearch)

    2. Modern Vector Search Filtering (used by vector stores)

    The Technical Debt

    The current implementation in VectorStoreTextSearch.cs shows the problem:

    var vectorSearchOptions = new VectorSearchOptions<TRecord>
    {
        #pragma warning disable CS0618 // VectorSearchFilter is obsolete
        OldFilter = searchOptions.Filter?.FilterClauses is not null 
            ? new VectorSearchFilter(searchOptions.Filter.FilterClauses) 
            : null,
        #pragma warning restore CS0618
        // ...
    }

    This code converts from the legacy TextSearchFilter to the already-obsolete VectorSearchFilter, rather than using the modern LINQ-based approach.

    Root Cause Analysis

    Related Work: PR #10273

    The foundation for LINQ-based filtering was established in PR #10273, which introduced:

    • VectorSearchOptions<TRecord>.Filter property using Expression<Func<TRecord, bool>>
    • Deprecation of the old VectorSearchFilter approach
    • Modern filtering infrastructure across vector database connectors

    However, ITextSearch was not updated to use this new infrastructure, creating the current inconsistency.

    Current Interface Design

    ITextSearch Interface:

    public interface ITextSearch
    {
        Task<KernelSearchResults<string>> SearchAsync(
            string query,
            TextSearchOptions? searchOptions = null,  // ← Uses legacy filtering
            CancellationToken cancellationToken = default);
    }

    TextSearchOptions Class:

    public sealed class TextSearchOptions
    {
        public TextSearchFilter? Filter { get; init; }  // ← Legacy clause-based filter
        // ...
    }
    
    [Experimental("SKEXP0001")]
    public sealed class TextSearchFilter  // ← Current filtering approach
    {
        public IEnumerable<FilterClause> FilterClauses { get; }
        // ...
    }

    Versus Modern VectorSearchOptions:

    public class VectorSearchOptions<TRecord>
    {
        [Obsolete("Use Filter instead")]
        public VectorSearchFilter? OldFilter { get; set; }  // ← Being phased out
        
        public Expression<Func<TRecord, bool>>? Filter { get; set; }  // ← Modern LINQ approach
        // ...
    }

    Impact Assessment

    Affected Components

    Based on codebase analysis, the following components require updates:

    Core Abstractions

    Implementation Classes

    Tests and Samples

    • 40+ test files across unit and integration tests
    • Multiple sample applications demonstrating text search

    Breaking Change Analysis

    This is a breaking change that requires careful migration strategy:

    1. API Surface: TextSearchOptions.Filter type changes from TextSearchFilter? to Expression<Func<TRecord, bool>>?
    2. Generic Constraint: Interface likely needs to become generic (ITextSearch<TRecord>)
    3. Implementation Impact: All text search implementations need to adapt to LINQ expressions

    Verification: Issue Not Addressed Elsewhere

    Checked Related PRs/Issues

    Current Status

    • Vector search: ✅ Uses modern LINQ filtering
    • Text search: ❌ Still uses legacy TextSearchFilter
    • Integration point: ❌ Uses obsolete conversion between the two systems

    Next Steps

    The solution requires:

    1. Interface modernization to support LINQ-based filtering
    2. Backward compatibility strategy to minimize breaking changes
    3. Implementation updates across all text search connectors
    4. Comprehensive testing to ensure no regression

    References


    Analysis completed on September 19, 2025

  4. 68 remaining items

  5. moved this from Sprint: Planned to Sprint: In Progress in Semantic Kernelon Feb 19, 2026
  6. added 4 commits that reference this issue on Mar 6, 2026
    b764d98
    90c71ba
    ab0aa44
    abdbad6
  7. added a commit that references this issue on Mar 20, 2026
    c2219a0
  8. added a commit that references this issue on Mar 21, 2026
    082e28e
  9. moved this from Sprint: In Progress to Sprint: Done in Semantic Kernelon Mar 21, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

.NETIssue or Pull requests regarding .NET codeBuildFeatures planned for next Build conferencememorymemory connectormsft.ext.vectordataRelated to Microsoft.Extensions.VectorData

Type

No type

Projects

Relationships

None yet

Development

No branches or pull requests

Issue actions