Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ Embedding<float> e
{
switch (property)
{
case KeyPropertyModel keyProperty:
case IKeyPropertyModel keyProperty:
if (!storageModel.TryGetValue(MongoConstants.MongoReservedKeyPropertyName, out var keyValue))
{
throw new InvalidOperationException("No key property was found in the record retrieved from storage.");
Expand All @@ -109,14 +109,14 @@ Embedding<float> e

continue;

case DataPropertyModel dataProperty:
case IDataPropertyModel dataProperty:
if (storageModel.TryGetValue(dataProperty.StorageName, out var dataValue))
{
result.Add(dataProperty.ModelName, GetDataPropertyValue(property.ModelName, property.Type, dataValue));
}
continue;

case VectorPropertyModel vectorProperty:
case IVectorPropertyModel vectorProperty:
if (includeVectors && storageModel.TryGetValue(vectorProperty.StorageName, out var vectorValue))
{
result.Add(
Expand Down
10 changes: 5 additions & 5 deletions dotnet/src/VectorData/AzureAISearch/AzureAISearchCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,15 +154,15 @@ public override async Task EnsureCollectionExistsAsync(CancellationToken cancell
{
switch (property)
{
case KeyPropertyModel p:
case IKeyPropertyModel p:
searchFields.Add(AzureAISearchCollectionCreateMapping.MapKeyField(p));
break;

case DataPropertyModel p:
case IDataPropertyModel p:
searchFields.Add(AzureAISearchCollectionCreateMapping.MapDataField(p));
break;

case VectorPropertyModel p:
case IVectorPropertyModel p:
(VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) = AzureAISearchCollectionCreateMapping.MapVectorField(p);

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

private static async ValueTask<ReadOnlyMemory<float>?> GetSearchVectorAsync<TInput>(TInput searchValue, VectorPropertyModel vectorProperty, CancellationToken cancellationToken)
private static async ValueTask<ReadOnlyMemory<float>?> GetSearchVectorAsync<TInput>(TInput searchValue, IVectorPropertyModel vectorProperty, CancellationToken cancellationToken)
where TInput : notnull
=> searchValue switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ internal static class AzureAISearchCollectionCreateMapping
/// </summary>
/// <param name="keyProperty">The key property definition.</param>
/// <returns>The <see cref="SearchableField"/> for the provided property definition.</returns>
public static SearchableField MapKeyField(KeyPropertyModel keyProperty)
public static SearchableField MapKeyField(IKeyPropertyModel keyProperty)
{
return new SearchableField(keyProperty.StorageName) { IsKey = true, IsFilterable = true };
}
Expand All @@ -29,7 +29,7 @@ public static SearchableField MapKeyField(KeyPropertyModel keyProperty)
/// <param name="dataProperty">The data property definition.</param>
/// <returns>The <see cref="SimpleField"/> for the provided property definition.</returns>
/// <exception cref="InvalidOperationException">Throws when the definition is missing required information.</exception>
public static SimpleField MapDataField(DataPropertyModel dataProperty)
public static SimpleField MapDataField(IDataPropertyModel dataProperty)
{
if (dataProperty.IsFullTextIndexed)
{
Expand Down Expand Up @@ -61,7 +61,7 @@ public static SimpleField MapDataField(DataPropertyModel dataProperty)
/// <param name="vectorProperty">The vector property definition.</param>
/// <returns>The <see cref="VectorSearchField"/> and required index configuration.</returns>
/// <exception cref="InvalidOperationException">Throws when the definition is missing required information, or unsupported options are configured.</exception>
public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) MapVectorField(VectorPropertyModel vectorProperty)
public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfiguration algorithmConfiguration, VectorSearchProfile vectorSearchProfile) MapVectorField(IVectorPropertyModel vectorProperty)
{
// Build a name for the profile and algorithm configuration based on the property name
// since we'll just create a separate one for each vector property.
Expand Down Expand Up @@ -91,7 +91,7 @@ public static (VectorSearchField vectorSearchField, VectorSearchAlgorithmConfigu
/// </summary>
/// <param name="vectorProperty">The vector property definition.</param>
/// <returns>The configured or default <see cref="IndexKind"/>.</returns>
public static string GetSKIndexKind(VectorPropertyModel vectorProperty)
public static string GetSKIndexKind(IVectorPropertyModel vectorProperty)
=> vectorProperty.IndexKind ?? IndexKind.Hnsw;

/// <summary>
Expand All @@ -101,7 +101,7 @@ public static string GetSKIndexKind(VectorPropertyModel vectorProperty)
/// <param name="vectorProperty">The vector property definition.</param>
/// <returns>The chosen <see cref="VectorSearchAlgorithmMetric"/>.</returns>
/// <exception cref="InvalidOperationException">Thrown if a distance function is chosen that isn't supported by Azure AI Search.</exception>
public static VectorSearchAlgorithmMetric GetSDKDistanceAlgorithm(VectorPropertyModel vectorProperty)
public static VectorSearchAlgorithmMetric GetSDKDistanceAlgorithm(IVectorPropertyModel vectorProperty)
=> vectorProperty.DistanceFunction switch
{
DistanceFunction.CosineSimilarity or null => VectorSearchAlgorithmMetric.Cosine,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
{
switch (property)
{
case KeyPropertyModel keyProperty:
case IKeyPropertyModel keyProperty:
var key = (string?)storageModel[keyProperty.StorageName]
?? throw new InvalidOperationException($"The key property '{keyProperty.StorageName}' is missing from the record retrieved from storage.");

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

continue;

case DataPropertyModel dataProperty:
case IDataPropertyModel dataProperty:
{
if (storageModel.TryGetPropertyValue(dataProperty.StorageName, out var value))
{
Expand All @@ -121,7 +121,7 @@ public JsonObject MapFromDataToStorageModel(Dictionary<string, object?> dataMode
continue;
}

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

case VectorPropertyModel vectorProperty when !includeVectors:
case IVectorPropertyModel vectorProperty when !includeVectors:
break;

default:
Expand Down
4 changes: 2 additions & 2 deletions dotnet/src/VectorData/Common/SqlFilterTranslator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ private void TranslateMember(MemberExpression memberExpression, bool isSearchCon
throw new NotSupportedException($"Member access for '{memberExpression.Member.Name}' is unsupported - only member access over the filter parameter are supported");
}

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

Expand Down Expand Up @@ -332,7 +332,7 @@ private void TranslateAny(Expression source, LambdaExpression lambda)
}
}

protected abstract void TranslateAnyContainsOverArrayColumn(PropertyModel property, object? values);
protected abstract void TranslateAnyContainsOverArrayColumn(IPropertyModel property, object? values);

private void TranslateUnary(UnaryExpression unary, bool isSearchCondition)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ internal static class CosmosMongoCollectionCreateMapping
/// <param name="numLists">Number of clusters that the inverted file (IVF) index uses to group the vector data.</param>
/// <param name="efConstruction">The size of the dynamic candidate list for constructing the graph.</param>
public static BsonArray GetVectorIndexes(
IReadOnlyList<VectorPropertyModel> vectorProperties,
IReadOnlyList<IVectorPropertyModel> vectorProperties,
HashSet<string?> uniqueIndexes,
int numLists,
int efConstruction)
Expand Down Expand Up @@ -71,7 +71,7 @@ public static BsonArray GetVectorIndexes(
/// <param name="dataProperties">Collection of data properties for index creation.</param>
/// <param name="uniqueIndexes">Collection of unique existing indexes to avoid creating duplicates.</param>
public static BsonArray GetFilterableDataIndexes(
IReadOnlyList<DataPropertyModel> dataProperties,
IReadOnlyList<IDataPropertyModel> dataProperties,
HashSet<string?> uniqueIndexes)
{
var indexArray = new BsonArray();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private BsonDocument TranslateEqualityComparison(BinaryExpression binary)
? this.GenerateEqualityComparison(property, leftConstant, binary.NodeType)
: throw new NotSupportedException("Invalid equality/comparison");

private BsonDocument GenerateEqualityComparison(PropertyModel property, object? value, ExpressionType nodeType)
private BsonDocument GenerateEqualityComparison(IPropertyModel property, object? value, ExpressionType nodeType)
{
if (value is null)
{
Expand Down
6 changes: 3 additions & 3 deletions dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ public class CosmosNoSqlCollection<TKey, TRecord> : VectorStoreCollection<TKey,

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

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

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

foreach (var propertyName in options.PartitionKeyProperties)
{
Expand Down Expand Up @@ -563,7 +563,7 @@ public override async IAsyncEnumerable<VectorSearchResult<TRecord>> SearchAsync<
}
}

private static async ValueTask<object> GetSearchVectorAsync<TInput>(TInput searchValue, VectorPropertyModel vectorProperty, CancellationToken cancellationToken)
private static async ValueTask<object> GetSearchVectorAsync<TInput>(TInput searchValue, IVectorPropertyModel vectorProperty, CancellationToken cancellationToken)
where TInput : notnull
=> searchValue switch
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,10 @@ public static QueryDefinition BuildSearchQuery<TRecord>(

var tableVariableName = CosmosNoSqlConstants.ContainerAlias;

IEnumerable<PropertyModel> projectionProperties = model.Properties;
IEnumerable<IPropertyModel> projectionProperties = model.Properties;
if (!includeVectors)
{
projectionProperties = projectionProperties.Where(p => p is not VectorPropertyModel);
projectionProperties = projectionProperties.Where(p => p is not IVectorPropertyModel);
}
var fieldsArgument = projectionProperties.Select(p => GeneratePropertyAccess(tableVariableName, p.StorageName));
var vectorDistanceArgument = $"VectorDistance({GeneratePropertyAccess(tableVariableName, vectorPropertyName)}, {VectorVariableName})";
Expand Down Expand Up @@ -167,10 +167,10 @@ internal static QueryDefinition BuildSearchQuery<TRecord>(
{
var tableVariableName = CosmosNoSqlConstants.ContainerAlias;

IEnumerable<PropertyModel> projectionProperties = model.Properties;
IEnumerable<IPropertyModel> projectionProperties = model.Properties;
if (!filterOptions.IncludeVectors)
{
projectionProperties = projectionProperties.Where(p => p is not VectorPropertyModel);
projectionProperties = projectionProperties.Where(p => p is not IVectorPropertyModel);
}

var fieldsArgument = projectionProperties.Select(field => GeneratePropertyAccess(tableVariableName, field.StorageName));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ static bool TryGetReadOnlyMemory<T>(object value, [NotNullWhen(true)] out ReadOn
{
switch (property)
{
case KeyPropertyModel keyProperty:
case IKeyPropertyModel keyProperty:
var key = (string?)storageModel[CosmosNoSqlConstants.ReservedKeyPropertyName]
?? throw new InvalidOperationException($"The key property '{keyProperty.StorageName}' is missing from the record retrieved from storage.");

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

continue;

case DataPropertyModel dataProperty:
case IDataPropertyModel dataProperty:
if (storageModel.TryGetPropertyValue(dataProperty.StorageName, out var dataValue))
{
result.Add(property.ModelName, dataValue.Deserialize(property.Type, jsonSerializerOptions));
}
continue;

case VectorPropertyModel vectorProperty:
case IVectorPropertyModel vectorProperty:
if (includeVectors && storageModel.TryGetPropertyValue(vectorProperty.StorageName, out var vectorValue))
{
if (vectorValue is not null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,7 +300,7 @@ private void TranslateAny(Expression source, LambdaExpression lambda)
}
}

private void GenerateAnyContains(PropertyModel property, object? values)
private void GenerateAnyContains(IPropertyModel property, object? values)
{
this._sql.Append("EXISTS(SELECT VALUE t FROM t IN ");
this.GeneratePropertyAccess(property);
Expand All @@ -309,7 +309,7 @@ private void GenerateAnyContains(PropertyModel property, object? values)
this._sql.Append(", t))");
}

private void GenerateAnyContains(PropertyModel property, QueryParameterExpression queryParameter)
private void GenerateAnyContains(IPropertyModel property, QueryParameterExpression queryParameter)
{
this._sql.Append("EXISTS(SELECT VALUE t FROM t IN ");
this.GeneratePropertyAccess(property);
Expand Down Expand Up @@ -361,7 +361,7 @@ protected void TranslateQueryParameter(string name, object? value)
this._sql.Append(name);
}

protected virtual void GeneratePropertyAccess(PropertyModel property)
protected virtual void GeneratePropertyAccess(IPropertyModel property)
=> this._sql
.Append(CosmosNoSqlConstants.ContainerAlias)
.Append("[\"")
Expand Down
8 changes: 4 additions & 4 deletions dotnet/src/VectorData/CosmosNoSql/CosmosNoSqlMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ internal sealed class CosmosNoSqlMapper<TRecord> : ICosmosNoSqlMapper<TRecord>
where TRecord : class
{
private readonly CollectionModel _model;
private readonly KeyPropertyModel _keyProperty;
private readonly IKeyPropertyModel _keyProperty;
private readonly JsonSerializerOptions _jsonSerializerOptions;

public CosmosNoSqlMapper(CollectionModel model, JsonSerializerOptions? jsonSerializerOptions)
Expand All @@ -41,8 +41,8 @@ public JsonObject MapFromDataToStorageModel(TRecord dataModel, int recordIndex,

// The key property in Azure CosmosDB NoSQL is always named 'id'.
// But the external JSON serializer used just above isn't aware of that, and will produce a JSON object with another name, taking into
// account e.g. naming policies. TemporaryStorageName gets populated in the model builder - containing that name - once VectorStoreModelBuildingOptions.ReservedKeyPropertyName is set
RenameJsonProperty(jsonObject, this._keyProperty.TemporaryStorageName!, CosmosNoSqlConstants.ReservedKeyPropertyName);
// account e.g. naming policies. SerializedKeyName gets populated in the model builder - containing that name - once VectorStoreModelBuildingOptions.ReservedKeyPropertyName is set
RenameJsonProperty(jsonObject, this._keyProperty.SerializedKeyName!, CosmosNoSqlConstants.ReservedKeyPropertyName);

// Go over the vector properties; inject any generated embeddings to overwrite the JSON serialized above.
// Also, for Embedding<T> properties we also need to overwrite with a simple array (since Embedding<T> gets serialized as a complex object).
Expand Down Expand Up @@ -116,7 +116,7 @@ public JsonObject MapFromDataToStorageModel(TRecord dataModel, int recordIndex,
public TRecord MapFromStorageToDataModel(JsonObject storageModel, bool includeVectors)
{
// See above comment.
RenameJsonProperty(storageModel, CosmosNoSqlConstants.ReservedKeyPropertyName, this._keyProperty.TemporaryStorageName!);
RenameJsonProperty(storageModel, CosmosNoSqlConstants.ReservedKeyPropertyName, this._keyProperty.SerializedKeyName!);

foreach (var vectorProperty in this._model.VectorProperties)
{
Expand Down
2 changes: 1 addition & 1 deletion dotnet/src/VectorData/MongoDB/MongoCollection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ public override async IAsyncEnumerable<VectorSearchResult<TRecord>> SearchAsync<
}
}

private static async ValueTask<float[]> GetSearchVectorArrayAsync<TInput>(TInput searchValue, VectorPropertyModel vectorProperty, CancellationToken cancellationToken)
private static async ValueTask<float[]> GetSearchVectorArrayAsync<TInput>(TInput searchValue, IVectorPropertyModel vectorProperty, CancellationToken cancellationToken)
where TInput : notnull
{
if (searchValue is float[] array)
Expand Down
Loading
Loading