Skip to content

Commit ab0aa44

Browse files
committed
Remove legacy filtering from MEVD providers
Closes #10456
1 parent 86d7a49 commit ab0aa44

File tree

41 files changed

+62
-1854
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+62
-1854
lines changed

dotnet/src/VectorData/AzureAISearch/AzureAISearchCollection.cs

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -442,9 +442,6 @@ public async IAsyncEnumerable<VectorSearchResult<TRecord>> HybridSearchAsync<TIn
442442
this._model,
443443
new()
444444
{
445-
#pragma warning disable CS0618 // Type or member is obsolete
446-
OldFilter = options.OldFilter,
447-
#pragma warning restore CS0618 // Type or member is obsolete
448445
Filter = options.Filter,
449446
VectorProperty = options.VectorProperty,
450447
Skip = options.Skip,
@@ -660,16 +657,10 @@ private static SearchOptions BuildSearchOptions(CollectionModel model, VectorSea
660657
throw new NotSupportedException(VectorDataStrings.IncludeVectorsNotSupportedWithEmbeddingGeneration);
661658
}
662659

663-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
664660
// Build filter object.
665-
var filter = options switch
666-
{
667-
{ OldFilter: not null, Filter: not null } => throw new ArgumentException("Either Filter or OldFilter can be specified, but not both"),
668-
{ OldFilter: VectorSearchFilter legacyFilter } => AzureAISearchCollectionSearchMapping.BuildLegacyFilterString(legacyFilter, model),
669-
{ Filter: Expression<Func<TRecord, bool>> newFilter } => new AzureAISearchFilterTranslator().Translate(newFilter, model),
670-
_ => null
671-
};
672-
#pragma warning restore CS0618
661+
var filter = options.Filter is not null
662+
? new AzureAISearchFilterTranslator().Translate(options.Filter, model)
663+
: null;
673664

674665
// Build search options.
675666
var searchOptions = new SearchOptions

dotnet/src/VectorData/AzureAISearch/AzureAISearchCollectionSearchMapping.cs

Lines changed: 0 additions & 78 deletions
This file was deleted.

dotnet/src/VectorData/CosmosMongoDB/CosmosMongoCollection.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -373,15 +373,9 @@ _ when vectorProperty.EmbeddingGenerationDispatcher is not null
373373
: throw new InvalidOperationException(VectorDataStrings.IncompatibleEmbeddingGeneratorWasConfiguredForInputType(typeof(TInput), vectorProperty.EmbeddingGenerator.GetType()))
374374
};
375375

376-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
377-
var filter = options switch
378-
{
379-
{ OldFilter: not null, Filter: not null } => throw new ArgumentException("Either Filter or OldFilter can be specified, but not both"),
380-
{ OldFilter: VectorSearchFilter legacyFilter } => CosmosMongoCollectionSearchMapping.BuildFilter(legacyFilter, this._model),
381-
{ Filter: Expression<Func<TRecord, bool>> newFilter } => new CosmosMongoFilterTranslator().Translate(newFilter, this._model),
382-
_ => null
383-
};
384-
#pragma warning restore CS0618
376+
var filter = options.Filter is not null
377+
? new CosmosMongoFilterTranslator().Translate(options.Filter, this._model)
378+
: null;
385379

386380
// Constructing a query to fetch "skip + top" total items
387381
// to perform skip logic locally, since skip option is not part of API.

dotnet/src/VectorData/CosmosMongoDB/CosmosMongoCollectionSearchMapping.cs

Lines changed: 0 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,6 @@
11
// Copyright (c) Microsoft. All rights reserved.
22

3-
using System;
4-
using System.Linq;
53
using Microsoft.Extensions.VectorData;
6-
using Microsoft.Extensions.VectorData.ProviderServices;
74
using Microsoft.SemanticKernel.Connectors.MongoDB;
85
using MongoDB.Bson;
96

@@ -20,75 +17,6 @@ internal static class CosmosMongoCollectionSearchMapping
2017
/// <summary>Returns distance function specified on vector property or default <see cref="MongoConstants.DefaultDistanceFunction"/>.</summary>
2118
public static string GetVectorPropertyDistanceFunction(string? distanceFunction) => !string.IsNullOrWhiteSpace(distanceFunction) ? distanceFunction! : MongoConstants.DefaultDistanceFunction;
2219

23-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
24-
/// <summary>
25-
/// Build Azure CosmosDB MongoDB filter from the provided <see cref="VectorSearchFilter"/>.
26-
/// </summary>
27-
/// <param name="vectorSearchFilter">The <see cref="VectorSearchFilter"/> to build Azure CosmosDB MongoDB filter from.</param>
28-
/// <param name="model">The model.</param>
29-
/// <exception cref="NotSupportedException">Thrown when the provided filter type is unsupported.</exception>
30-
/// <exception cref="InvalidOperationException">Thrown when property name specified in filter doesn't exist.</exception>
31-
public static BsonDocument? BuildFilter(VectorSearchFilter? vectorSearchFilter, CollectionModel model)
32-
{
33-
const string EqualOperator = "$eq";
34-
35-
var filterClauses = vectorSearchFilter?.FilterClauses.ToList();
36-
37-
if (filterClauses is not { Count: > 0 })
38-
{
39-
return null;
40-
}
41-
42-
var filter = new BsonDocument();
43-
44-
foreach (var filterClause in filterClauses)
45-
{
46-
string propertyName;
47-
BsonValue propertyValue;
48-
string filterOperator;
49-
50-
if (filterClause is EqualToFilterClause equalToFilterClause)
51-
{
52-
propertyName = equalToFilterClause.FieldName;
53-
propertyValue = BsonValueFactory.Create(equalToFilterClause.Value);
54-
filterOperator = EqualOperator;
55-
}
56-
else
57-
{
58-
throw new NotSupportedException(
59-
$"Unsupported filter clause type '{filterClause.GetType().Name}'. " +
60-
$"Supported filter clause types are: {string.Join(", ", [
61-
nameof(EqualToFilterClause)])}");
62-
}
63-
64-
if (!model.PropertyMap.TryGetValue(propertyName, out var property))
65-
{
66-
throw new InvalidOperationException($"Property name '{propertyName}' provided as part of the filter clause is not a valid property name.");
67-
}
68-
69-
var storageName = property.StorageName;
70-
71-
if (filter.Contains(storageName))
72-
{
73-
if (filter[storageName] is BsonDocument document && document.Contains(filterOperator))
74-
{
75-
throw new NotSupportedException(
76-
$"Filter with operator '{filterOperator}' is already added to '{propertyName}' property. " +
77-
"Multiple filters of the same type in the same property are not supported.");
78-
}
79-
80-
filter[storageName][filterOperator] = propertyValue;
81-
}
82-
else
83-
{
84-
filter[storageName] = new BsonDocument() { [filterOperator] = propertyValue };
85-
}
86-
}
87-
88-
return filter;
89-
}
90-
#pragma warning restore CS0618 // VectorSearchFilter is obsolete
91-
9220
/// <summary>Returns search part of the search query for <see cref="IndexKind.Hnsw"/> index kind.</summary>
9321
public static BsonDocument GetSearchQueryForHnswIndex<TVector>(
9422
TVector vector,

dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlCollection.cs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -541,7 +541,6 @@ public override async IAsyncEnumerable<VectorSearchResult<TRecord>> SearchAsync<
541541
var vectorProperty = this._model.GetVectorPropertyOrSingle(options);
542542
object vector = await GetSearchVectorAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false);
543543

544-
#pragma warning disable CS0618 // Type or member is obsolete
545544
var queryDefinition = CosmosNoSqlCollectionQueryBuilder.BuildSearchQuery(
546545
vector,
547546
null,
@@ -550,13 +549,11 @@ public override async IAsyncEnumerable<VectorSearchResult<TRecord>> SearchAsync<
550549
vectorProperty.DistanceFunction,
551550
textPropertyName: null,
552551
ScorePropertyName,
553-
options.OldFilter,
554552
options.Filter,
555553
options.ScoreThreshold,
556554
top,
557555
options.Skip,
558556
options.IncludeVectors);
559-
#pragma warning restore CS0618 // Type or member is obsolete
560557

561558
var searchResults = this.GetItemsAsync<JsonObject>(queryDefinition, OperationName, cancellationToken);
562559

@@ -645,7 +642,6 @@ public async IAsyncEnumerable<VectorSearchResult<TRecord>> HybridSearchAsync<TIn
645642
object vector = await GetSearchVectorAsync(searchValue, vectorProperty, cancellationToken).ConfigureAwait(false);
646643
var textProperty = this._model.GetFullTextDataPropertyOrSingle(options.AdditionalProperty);
647644

648-
#pragma warning disable CS0618 // Type or member is obsolete
649645
var queryDefinition = CosmosNoSqlCollectionQueryBuilder.BuildSearchQuery<TRecord>(
650646
vector,
651647
keywords,
@@ -654,13 +650,11 @@ public async IAsyncEnumerable<VectorSearchResult<TRecord>> HybridSearchAsync<TIn
654650
vectorProperty.DistanceFunction,
655651
textProperty.StorageName,
656652
ScorePropertyName,
657-
options.OldFilter,
658653
options.Filter,
659654
options.ScoreThreshold,
660655
top,
661656
options.Skip,
662657
options.IncludeVectors);
663-
#pragma warning restore CS0618 // Type or member is obsolete
664658

665659
var searchResults = this.GetItemsAsync<JsonObject>(queryDefinition, OperationName, cancellationToken);
666660

dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlCollectionQueryBuilder.cs

Lines changed: 3 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,6 @@ public static QueryDefinition BuildSearchQuery<TRecord>(
2727
string? distanceFunction,
2828
string? textPropertyName,
2929
string scorePropertyName,
30-
#pragma warning disable CS0618 // Type or member is obsolete
31-
VectorSearchFilter? oldFilter,
32-
#pragma warning restore CS0618 // Type or member is obsolete
3330
Expression<Func<TRecord, bool>>? filter,
3431
double? scoreThreshold,
3532
int top,
@@ -54,16 +51,10 @@ public static QueryDefinition BuildSearchQuery<TRecord>(
5451

5552
var selectClauseArguments = string.Join(",", [.. fieldsArgument, vectorDistanceArgumentWithAlias]);
5653

57-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
5854
// Build filter object.
59-
var (filterClause, filterParameters) = (OldFilter: oldFilter, Filter: filter) switch
60-
{
61-
{ OldFilter: not null, Filter: not null } => throw new ArgumentException("Either Filter or OldFilter can be specified, but not both"),
62-
{ OldFilter: VectorSearchFilter legacyFilter } => BuildSearchFilter(legacyFilter, model),
63-
{ Filter: Expression<Func<TRecord, bool>> newFilter } => new CosmosNoSqlFilterTranslator().Translate(newFilter, model),
64-
_ => (null, [])
65-
};
66-
#pragma warning restore CS0618 // VectorSearchFilter is obsolete
55+
var (filterClause, filterParameters) = filter is not null
56+
? new CosmosNoSqlFilterTranslator().Translate(filter, model)
57+
: ((string?)null, new Dictionary<string, object?>());
6758

6859
var queryParameters = new Dictionary<string, object?>
6960
{
@@ -229,68 +220,6 @@ internal static QueryDefinition BuildSearchQuery<TRecord>(
229220

230221
#region private
231222

232-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
233-
private static (string WhereClause, Dictionary<string, object?> Parameters) BuildSearchFilter(
234-
VectorSearchFilter filter,
235-
CollectionModel model)
236-
{
237-
const string ArrayContainsOperator = "ARRAY_CONTAINS";
238-
const string ConditionValueVariableName = "@cv";
239-
240-
var tableVariableName = CosmosNoSqlConstants.ContainerAlias;
241-
242-
var filterClauses = filter.FilterClauses.ToList();
243-
244-
var whereClauseBuilder = new StringBuilder();
245-
var queryParameters = new Dictionary<string, object?>();
246-
247-
for (var i = 0; i < filterClauses.Count; i++)
248-
{
249-
if (i > 0)
250-
{
251-
whereClauseBuilder.Append(" AND ");
252-
}
253-
var filterClause = filterClauses[i];
254-
255-
string queryParameterName = $"{ConditionValueVariableName}{i}";
256-
object queryParameterValue;
257-
258-
if (filterClause is EqualToFilterClause equalToFilterClause)
259-
{
260-
var propertyName = GetStoragePropertyName(equalToFilterClause.FieldName, model);
261-
whereClauseBuilder
262-
.Append(GeneratePropertyAccess(tableVariableName, propertyName))
263-
.Append(" = ")
264-
.Append(queryParameterName);
265-
queryParameterValue = equalToFilterClause.Value;
266-
}
267-
else if (filterClause is AnyTagEqualToFilterClause anyTagEqualToFilterClause)
268-
{
269-
var propertyName = GetStoragePropertyName(anyTagEqualToFilterClause.FieldName, model);
270-
whereClauseBuilder.Append(ArrayContainsOperator)
271-
.Append('(')
272-
.Append(GeneratePropertyAccess(tableVariableName, propertyName))
273-
.Append(", ")
274-
.Append(queryParameterName)
275-
.Append(')');
276-
queryParameterValue = anyTagEqualToFilterClause.Value;
277-
}
278-
else
279-
{
280-
throw new NotSupportedException(
281-
$"Unsupported filter clause type '{filterClause.GetType().Name}'. " +
282-
$"Supported filter clause types are: {string.Join(", ", [
283-
nameof(EqualToFilterClause),
284-
nameof(AnyTagEqualToFilterClause)])}");
285-
}
286-
287-
queryParameters.Add(queryParameterName, queryParameterValue);
288-
}
289-
290-
return (whereClauseBuilder.ToString(), queryParameters);
291-
}
292-
#pragma warning restore CS0618 // VectorSearchFilter is obsolete
293-
294223
private static string GetStoragePropertyName(string propertyName, CollectionModel model)
295224
{
296225
if (!model.PropertyMap.TryGetValue(propertyName, out var property))

dotnet/src/VectorData/InMemory/InMemoryCollection.cs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -282,17 +282,11 @@ _ when vectorProperty.EmbeddingGenerationDispatcher is not null
282282
: throw new InvalidOperationException(VectorDataStrings.IncompatibleEmbeddingGeneratorWasConfiguredForInputType(typeof(TInput), vectorProperty.EmbeddingGenerator.GetType()))
283283
};
284284

285-
#pragma warning disable CS0618 // VectorSearchFilter is obsolete
286285
// Filter records using the provided filter before doing the vector comparison.
287286
var allValues = this.GetCollectionDictionary().Values.Cast<InMemoryRecordWrapper<TRecord>>();
288-
var filteredRecords = options switch
289-
{
290-
{ OldFilter: not null, Filter: not null } => throw new ArgumentException("Either Filter or OldFilter can be specified, but not both"),
291-
{ OldFilter: VectorSearchFilter legacyFilter } => InMemoryCollectionSearchMapping.FilterRecords(legacyFilter, allValues),
292-
{ Filter: Expression<Func<TRecord, bool>> newFilter } => allValues.AsQueryable().Where(this.ConvertFilter(newFilter)),
293-
_ => allValues
294-
};
295-
#pragma warning restore CS0618 // VectorSearchFilter is obsolete
287+
var filteredRecords = options.Filter is not null
288+
? allValues.AsQueryable().Where(this.ConvertFilter(options.Filter))
289+
: allValues;
296290

297291
// Compare each vector in the filtered results with the provided vector.
298292
var results = filteredRecords.Select<InMemoryRecordWrapper<TRecord>, (TRecord record, float score)?>(wrapper =>

0 commit comments

Comments
 (0)