Skip to content

Commit abcdb5a

Browse files
rojiCopilot
andcommitted
Expose read-only interface views of properties from the model
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
1 parent 4a2d10f commit abcdb5a

55 files changed

Lines changed: 346 additions & 175 deletions

File tree

Some content is hidden

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

dotnet/src/InternalUtilities/connectors/Memory/MongoDB/MongoDynamicMapper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ Embedding<float> e
9090
{
9191
switch (property)
9292
{
93-
case KeyPropertyModel keyProperty:
93+
case IKeyPropertyModel keyProperty:
9494
if (!storageModel.TryGetValue(MongoConstants.MongoReservedKeyPropertyName, out var keyValue))
9595
{
9696
throw new InvalidOperationException("No key property was found in the record retrieved from storage.");
@@ -109,14 +109,14 @@ Embedding<float> e
109109

110110
continue;
111111

112-
case DataPropertyModel dataProperty:
112+
case IDataPropertyModel dataProperty:
113113
if (storageModel.TryGetValue(dataProperty.StorageName, out var dataValue))
114114
{
115115
result.Add(dataProperty.ModelName, GetDataPropertyValue(property.ModelName, property.Type, dataValue));
116116
}
117117
continue;
118118

119-
case VectorPropertyModel vectorProperty:
119+
case IVectorPropertyModel vectorProperty:
120120
if (includeVectors && storageModel.TryGetValue(vectorProperty.StorageName, out var vectorValue))
121121
{
122122
result.Add(

dotnet/src/VectorData/AzureAISearch/AzureAISearchCollection.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -154,15 +154,15 @@ public override async Task EnsureCollectionExistsAsync(CancellationToken cancell
154154
{
155155
switch (property)
156156
{
157-
case KeyPropertyModel p:
157+
case IKeyPropertyModel p:
158158
searchFields.Add(AzureAISearchCollectionCreateMapping.MapKeyField(p));
159159
break;
160160

161-
case DataPropertyModel p:
161+
case IDataPropertyModel p:
162162
searchFields.Add(AzureAISearchCollectionCreateMapping.MapDataField(p));
163163
break;
164164

165-
case VectorPropertyModel p:
165+
case IVectorPropertyModel p:
166166
(VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) = AzureAISearchCollectionCreateMapping.MapVectorField(p);
167167

168168
// Add the search field, plus its profile and algorithm configuration to the search config.
@@ -361,7 +361,7 @@ public override IAsyncEnumerable<TRecord> GetAsync(Expression<Func<TRecord, bool
361361
{
362362
foreach (var pair in options.OrderBy(new()).Values)
363363
{
364-
PropertyModel property = this._model.GetDataOrKeyProperty(pair.PropertySelector);
364+
IPropertyModel property = this._model.GetDataOrKeyProperty(pair.PropertySelector);
365365
string name = property.StorageName;
366366
// From https://learn.microsoft.com/dotnet/api/azure.search.documents.searchoptions.orderby:
367367
// "Each expression can be followed by asc to indicate ascending, or desc to indicate descending".
@@ -466,7 +466,7 @@ floatVector is null
466466
}
467467
}
468468

469-
private static async ValueTask<ReadOnlyMemory<float>?> GetSearchVectorAsync<TInput>(TInput searchValue, VectorPropertyModel vectorProperty, CancellationToken cancellationToken)
469+
private static async ValueTask<ReadOnlyMemory<float>?> GetSearchVectorAsync<TInput>(TInput searchValue, IVectorPropertyModel vectorProperty, CancellationToken cancellationToken)
470470
where TInput : notnull
471471
=> searchValue switch
472472
{

dotnet/src/VectorData/AzureAISearch/AzureAISearchCollectionCreateMapping.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ internal static class AzureAISearchCollectionCreateMapping
1818
/// </summary>
1919
/// <param name="keyProperty">The key property definition.</param>
2020
/// <returns>The <see cref="SearchableField"/> for the provided property definition.</returns>
21-
public static SearchableField MapKeyField(KeyPropertyModel keyProperty)
21+
public static SearchableField MapKeyField(IKeyPropertyModel keyProperty)
2222
{
2323
return new SearchableField(keyProperty.StorageName) { IsKey = true, IsFilterable = true };
2424
}
@@ -29,7 +29,7 @@ public static SearchableField MapKeyField(KeyPropertyModel keyProperty)
2929
/// <param name="dataProperty">The data property definition.</param>
3030
/// <returns>The <see cref="SimpleField"/> for the provided property definition.</returns>
3131
/// <exception cref="InvalidOperationException">Throws when the definition is missing required information.</exception>
32-
public static SimpleField MapDataField(DataPropertyModel dataProperty)
32+
public static SimpleField MapDataField(IDataPropertyModel dataProperty)
3333
{
3434
if (dataProperty.IsFullTextIndexed)
3535
{
@@ -61,7 +61,7 @@ public static SimpleField MapDataField(DataPropertyModel dataProperty)
6161
/// <param name="vectorProperty">The vector property definition.</param>
6262
/// <returns>The <see cref="VectorSearchField"/> and required index configuration.</returns>
6363
/// <exception cref="InvalidOperationException">Throws when the definition is missing required information, or unsupported options are configured.</exception>
64-
public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) MapVectorField(VectorPropertyModel vectorProperty)
64+
public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) MapVectorField(IVectorPropertyModel vectorProperty)
6565
{
6666
// Build a name for the profile and algorithm configuration based on the property name
6767
// since we'll just create a separate one for each vector property.
@@ -91,7 +91,7 @@ public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfigu
9191
/// </summary>
9292
/// <param name="vectorProperty">The vector property definition.</param>
9393
/// <returns>The configured or default <see cref="IndexKind"/>.</returns>
94-
public static string GetSKIndexKind(VectorPropertyModel vectorProperty)
94+
public static string GetSKIndexKind(IVectorPropertyModel vectorProperty)
9595
=> vectorProperty.IndexKind ?? IndexKind.Hnsw;
9696

9797
/// <summary>
@@ -101,7 +101,7 @@ public static string GetSKIndexKind(VectorPropertyModel vectorProperty)
101101
/// <param name="vectorProperty">The vector property definition.</param>
102102
/// <returns>The chosen <see cref="VectorSearchAlgorithmMetric"/>.</returns>
103103
/// <exception cref="InvalidOperationException">Thrown if a distance function is chosen that isn't supported by Azure AI Search.</exception>
104-
public static VectorSearchAlgorithmMetric GetSDKDistanceAlgorithm(VectorPropertyModel vectorProperty)
104+
public static VectorSearchAlgorithmMetric GetSDKDistanceAlgorithm(IVectorPropertyModel vectorProperty)
105105
=> vectorProperty.DistanceFunction switch
106106
{
107107
DistanceFunction.CosineSimilarity or null => VectorSearchAlgorithmMetric.Cosine,

dotnet/src/VectorData/AzureAISearch/AzureAISearchDynamicMapper.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
9999
{
100100
switch (property)
101101
{
102-
case KeyPropertyModel keyProperty:
102+
case IKeyPropertyModel keyProperty:
103103
var key = (string?)storageModel[keyProperty.StorageName]
104104
?? throw new InvalidOperationException($"The key property '{keyProperty.StorageName}' is missing from the record retrieved from storage.");
105105

@@ -112,7 +112,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
112112

113113
continue;
114114

115-
case DataPropertyModel dataProperty:
115+
case IDataPropertyModel dataProperty:
116116
{
117117
if (storageModel.TryGetPropertyValue(dataProperty.StorageName, out var value))
118118
{
@@ -121,7 +121,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
121121
continue;
122122
}
123123

124-
case VectorPropertyModel vectorProperty when includeVectors:
124+
case IVectorPropertyModel vectorProperty when includeVectors:
125125
{
126126
if (storageModel.TryGetPropertyValue(vectorProperty.StorageName, out var value))
127127
{
@@ -147,7 +147,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
147147
continue;
148148
}
149149

150-
case VectorPropertyModel vectorProperty when !includeVectors:
150+
case IVectorPropertyModel vectorProperty when !includeVectors:
151151
break;
152152

153153
default:

dotnet/src/VectorData/Common/SqlFilterTranslator.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ private void TranslateMember(MemberExpression memberExpression, bool isSearchCon
196196
throw new NotSupportedException($"Member access for '{memberExpression.Member.Name}' is unsupported - only member access over the filter parameter are supported");
197197
}
198198

199-
protected virtual void GenerateColumn(PropertyModel property, bool isSearchCondition = false)
199+
protected virtual void GenerateColumn(IPropertyModel property, bool isSearchCondition = false)
200200
// StorageName is considered to be a safe input, we quote and escape it mostly to produce valid SQL.
201201
=> this._sql.Append('"').Append(property.StorageName.Replace("\"", "\"\"")).Append('"');
202202

@@ -332,7 +332,7 @@ private void TranslateAny(Expression source, LambdaExpression lambda)
332332
}
333333
}
334334

335-
protected abstract void TranslateAnyContainsOverArrayColumn(PropertyModel property, object? values);
335+
protected abstract void TranslateAnyContainsOverArrayColumn(IPropertyModel property, object? values);
336336

337337
private void TranslateUnary(UnaryExpression unary, bool isSearchCondition)
338338
{

dotnet/src/VectorData/CosmosMongoDB/CosmosMongoCollectionCreateMapping.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ internal static class CosmosMongoCollectionCreateMapping
2121
/// <param name="numLists">Number of clusters that the inverted file (IVF) index uses to group the vector data.</param>
2222
/// <param name="efConstruction">The size of the dynamic candidate list for constructing the graph.</param>
2323
public static BsonArray GetVectorIndexes(
24-
IReadOnlyList<VectorPropertyModel> vectorProperties,
24+
IReadOnlyList<IVectorPropertyModel> vectorProperties,
2525
HashSet<string?> uniqueIndexes,
2626
int numLists,
2727
int efConstruction)
@@ -71,7 +71,7 @@ public static BsonArray GetVectorIndexes(
7171
/// <param name="dataProperties">Collection of data properties for index creation.</param>
7272
/// <param name="uniqueIndexes">Collection of unique existing indexes to avoid creating duplicates.</param>
7373
public static BsonArray GetFilterableDataIndexes(
74-
IReadOnlyList<DataPropertyModel> dataProperties,
74+
IReadOnlyList<IDataPropertyModel> dataProperties,
7575
HashSet<string?> uniqueIndexes)
7676
{
7777
var indexArray = new BsonArray();

dotnet/src/VectorData/CosmosMongoDB/CosmosMongoFilterTranslator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ private BsonDocument TranslateEqualityComparison(BinaryExpression binary)
6262
? this.GenerateEqualityComparison(property, leftConstant, binary.NodeType)
6363
: throw new NotSupportedException("Invalid equality/comparison");
6464

65-
private BsonDocument GenerateEqualityComparison(PropertyModel property, object? value, ExpressionType nodeType)
65+
private BsonDocument GenerateEqualityComparison(IPropertyModel property, object? value, ExpressionType nodeType)
6666
{
6767
if (value is null)
6868
{

dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlCollection.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public class CosmosNoSqlCollection<TKey, TRecord> : VectorStoreCollection<TKey,
5656

5757
// TODO: Refactor this into the model
5858
/// <summary>The properties to use as partition key (supports hierarchical partition keys up to 3 levels).</summary>
59-
private readonly List<PropertyModel> _partitionKeyProperties;
59+
private readonly List<IPropertyModel> _partitionKeyProperties;
6060

6161
/// <summary>The mapper to use when mapping between the consumer data model and the Azure CosmosDB NoSQL record.</summary>
6262
private readonly ICosmosNoSqlMapper<TRecord> _mapper;
@@ -181,7 +181,7 @@ internal CosmosNoSqlCollection(
181181
throw new ArgumentException("Cosmos DB supports at most 3 levels of hierarchical partition keys.");
182182
}
183183

184-
this._partitionKeyProperties = new List<PropertyModel>(options.PartitionKeyProperties.Count);
184+
this._partitionKeyProperties = new List<IPropertyModel>(options.PartitionKeyProperties.Count);
185185

186186
foreach (var propertyName in options.PartitionKeyProperties)
187187
{
@@ -563,7 +563,7 @@ public override async IAsyncEnumerable<VectorSearchResult<TRecord>> SearchAsync<
563563
}
564564
}
565565

566-
private static async ValueTask<object> GetSearchVectorAsync<TInput>(TInput searchValue, VectorPropertyModel vectorProperty, CancellationToken cancellationToken)
566+
private static async ValueTask<object> GetSearchVectorAsync<TInput>(TInput searchValue, IVectorPropertyModel vectorProperty, CancellationToken cancellationToken)
567567
where TInput : notnull
568568
=> searchValue switch
569569
{

dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlCollectionQueryBuilder.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,10 @@ public static QueryDefinition BuildSearchQuery<TRecord>(
4040

4141
var tableVariableName = CosmosNoSqlConstants.ContainerAlias;
4242

43-
IEnumerable<PropertyModel> projectionProperties = model.Properties;
43+
IEnumerable<IPropertyModel> projectionProperties = model.Properties;
4444
if (!includeVectors)
4545
{
46-
projectionProperties = projectionProperties.Where(p => p is not VectorPropertyModel);
46+
projectionProperties = projectionProperties.Where(p => p is not IVectorPropertyModel);
4747
}
4848
var fieldsArgument = projectionProperties.Select(p => GeneratePropertyAccess(tableVariableName, p.StorageName));
4949
var vectorDistanceArgument = $"VectorDistance({GeneratePropertyAccess(tableVariableName, vectorPropertyName)}, {VectorVariableName})";
@@ -167,10 +167,10 @@ internal static QueryDefinition BuildSearchQuery<TRecord>(
167167
{
168168
var tableVariableName = CosmosNoSqlConstants.ContainerAlias;
169169

170-
IEnumerable<PropertyModel> projectionProperties = model.Properties;
170+
IEnumerable<IPropertyModel> projectionProperties = model.Properties;
171171
if (!filterOptions.IncludeVectors)
172172
{
173-
projectionProperties = projectionProperties.Where(p => p is not VectorPropertyModel);
173+
projectionProperties = projectionProperties.Where(p => p is not IVectorPropertyModel);
174174
}
175175

176176
var fieldsArgument = projectionProperties.Select(field => GeneratePropertyAccess(tableVariableName, field.StorageName));

dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlDynamicMapper.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ static bool TryGetReadOnlyMemory<T>(object value, [NotNullWhen(true)] out ReadOn
123123
{
124124
switch (property)
125125
{
126-
case KeyPropertyModel keyProperty:
126+
case IKeyPropertyModel keyProperty:
127127
var key = (string?)storageModel[CosmosNoSqlConstants.ReservedKeyPropertyName]
128128
?? throw new InvalidOperationException($"The key property '{keyProperty.StorageName}' is missing from the record retrieved from storage.");
129129

@@ -136,14 +136,14 @@ static bool TryGetReadOnlyMemory<T>(object value, [NotNullWhen(true)] out ReadOn
136136

137137
continue;
138138

139-
case DataPropertyModel dataProperty:
139+
case IDataPropertyModel dataProperty:
140140
if (storageModel.TryGetPropertyValue(dataProperty.StorageName, out var dataValue))
141141
{
142142
result.Add(property.ModelName, dataValue.Deserialize(property.Type, jsonSerializerOptions));
143143
}
144144
continue;
145145

146-
case VectorPropertyModel vectorProperty:
146+
case IVectorPropertyModel vectorProperty:
147147
if (includeVectors && storageModel.TryGetPropertyValue(vectorProperty.StorageName, out var vectorValue))
148148
{
149149
if (vectorValue is not null)

0 commit comments

Comments
 (0)