File: HybridSearchOptions.cs
Project: ..\..\..\src\Libraries\Microsoft.Extensions.VectorData.Abstractions\Microsoft.Extensions.VectorData.Abstractions.csproj (Microsoft.Extensions.VectorData.Abstractions)
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
 
using System;
using System.Linq.Expressions;
using Microsoft.Shared.Diagnostics;
 
namespace Microsoft.Extensions.VectorData;
 
/// <summary>
/// Defines options for hybrid search when using a dense vector and string keywords to do the search.
/// </summary>
/// <typeparam name="TRecord">The type of the record.</typeparam>
public class HybridSearchOptions<TRecord>
{
    /// <summary>
    /// Gets or sets a search filter to use before doing the hybrid search.
    /// </summary>
    public Expression<Func<TRecord, bool>>? Filter { get; set; }
 
    /// <summary>
    /// Gets or sets the target dense vector property to search on.
    /// Only needs to be set when the collection has multiple vector properties.
    /// </summary>
    /// <remarks>
    /// If this property isn't set, <see cref="IKeywordHybridSearchable{TRecord}.HybridSearchAsync{TInput}(TInput, System.Collections.Generic.ICollection{string}, int, Microsoft.Extensions.VectorData.HybridSearchOptions{TRecord}?, System.Threading.CancellationToken)"/> checks if there is a vector property to use by default, and
    /// throws if either none or multiple exist.
    /// </remarks>
    public Expression<Func<TRecord, object?>>? VectorProperty { get; set; }
 
    /// <summary>
    /// Gets or sets the additional target property to do the text or keyword search on.
    /// The property must have full text indexing enabled.
    /// </summary>
    /// <remarks>
    /// If this property isn't set, <see cref="IKeywordHybridSearchable{TRecord}.HybridSearchAsync{TInput}(TInput, System.Collections.Generic.ICollection{string}, int, Microsoft.Extensions.VectorData.HybridSearchOptions{TRecord}?, System.Threading.CancellationToken)"/> checks if there is a text property with full text indexing enabled, and
    /// throws an exception if either none or multiple exist.
    /// </remarks>
    public Expression<Func<TRecord, object?>>? AdditionalProperty { get; set; }
 
    /// <summary>
    /// Gets or sets the number of results to skip before returning results, that is, the index of the first result to return.
    /// </summary>
    /// <exception cref="ArgumentOutOfRangeException">The value is less than 0.</exception>
    public int Skip
    {
        get;
        set
        {
            if (value < 0)
            {
                Throw.ArgumentOutOfRangeException(nameof(value), "Skip must be greater than or equal to 0.");
            }
 
            field = value;
        }
    }
 
    /// <summary>
    /// Gets or sets a value indicating whether to include vectors in the retrieval result.
    /// </summary>
    public bool IncludeVectors { get; set; }
 
    /// <summary>
    /// Gets or sets the score threshold to filter results.
    /// </summary>
    /// <remarks>
    /// <para>
    /// The meaning of the score is a combination of the distance function configured for <see cref="VectorProperty"/> and the text
    /// relevance score for the full-text search on <see cref="AdditionalProperty"/>.
    /// </para>
    /// <para>
    /// The range of scores also depends on the distance function; for example, cosine similarity/distance scores
    /// fall within 0 to 1, while Euclidean distance is unbounded. Scores can also differ between vector databases.
    /// </para>
    /// </remarks>
    public double? ScoreThreshold { get; set; }
}