diff --git a/dotnet/samples/Concepts/Concepts.csproj b/dotnet/samples/Concepts/Concepts.csproj
index 0ac3dc6a4586..808841ad2d37 100644
--- a/dotnet/samples/Concepts/Concepts.csproj
+++ b/dotnet/samples/Concepts/Concepts.csproj
@@ -8,7 +8,7 @@
false
true
- $(NoWarn);CS8618,IDE0009,IDE1006,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0020,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0101,SKEXP0110,OPENAI001,CA1724
+ $(NoWarn);CS8618,IDE0009,IDE1006,CA1051,CA1050,CA1707,CA1054,CA2007,VSTHRD111,CS1591,RCS1110,RCS1243,CA5394,SKEXP0001,SKEXP0010,SKEXP0020,SKEXP0040,SKEXP0050,SKEXP0060,SKEXP0070,SKEXP0101,SKEXP0110,OPENAI001,CA1724,MEVD9000
Library
5ee045b0-aea3-4f08-8d31-32d1a6f8fed0
diff --git a/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStore.cs b/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStore.cs
index 6848b38af48f..4fd62592adf3 100644
--- a/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStore.cs
+++ b/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStore.cs
@@ -40,6 +40,16 @@ public IVectorStoreRecordCollection GetCollection(
return embeddingStore;
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ ArgumentNullException.ThrowIfNull(serviceType);
+
+ return
+ serviceKey is null && serviceType.IsInstanceOfType(this) ? this :
+ this._decoratedVectorStore.GetService(serviceType, serviceKey);
+ }
+
///
public IAsyncEnumerable ListCollectionNamesAsync(CancellationToken cancellationToken = default)
{
diff --git a/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStoreRecordCollection.cs b/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStoreRecordCollection.cs
index 9702e938b2d9..8e53b42711af 100644
--- a/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStoreRecordCollection.cs
+++ b/dotnet/samples/Concepts/Memory/VectorStoreEmbeddingGeneration/TextEmbeddingVectorStoreRecordCollection.cs
@@ -132,6 +132,16 @@ public async Task> VectorizableTextSearchAsync(stri
return await this.VectorizedSearchAsync(embeddingValue, top, options, cancellationToken).ConfigureAwait(false);
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ ArgumentNullException.ThrowIfNull(serviceType);
+
+ return
+ serviceKey is null && serviceType.IsInstanceOfType(this) ? this :
+ this._decoratedVectorStoreRecordCollection.GetService(serviceType, serviceKey);
+ }
+
///
/// Generate and add embeddings for each embedding field that has a on the provided record.
///
diff --git a/dotnet/samples/Concepts/Search/VectorStore_TextSearch.cs b/dotnet/samples/Concepts/Search/VectorStore_TextSearch.cs
index f5d39c702790..490a379c5cd8 100644
--- a/dotnet/samples/Concepts/Search/VectorStore_TextSearch.cs
+++ b/dotnet/samples/Concepts/Search/VectorStore_TextSearch.cs
@@ -150,6 +150,16 @@ public async Task> VectorizableTextSearchAsync(stri
return await vectorizedSearch.VectorizedSearchAsync(vectorizedQuery, top, options, cancellationToken);
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ ArgumentNullException.ThrowIfNull(serviceType);
+
+ return
+ serviceKey is null && serviceType.IsInstanceOfType(this) ? this :
+ vectorizedSearch.GetService(serviceType, serviceKey);
+ }
}
///
diff --git a/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreRecordCollectionTests.cs b/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreRecordCollectionTests.cs
index e9be1d92180c..9cdc26661a0c 100644
--- a/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreRecordCollectionTests.cs
+++ b/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreRecordCollectionTests.cs
@@ -41,6 +41,7 @@ public AzureAISearchVectorStoreRecordCollectionTests()
this._searchClientMock = new Mock(MockBehavior.Strict);
this._searchIndexClientMock = new Mock(MockBehavior.Strict);
this._searchIndexClientMock.Setup(x => x.GetSearchClient(TestCollectionName)).Returns(this._searchClientMock.Object);
+ this._searchIndexClientMock.Setup(x => x.ServiceName).Returns("TestService");
}
[Theory]
diff --git a/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreTests.cs b/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreTests.cs
index b79b048a5f38..f4eed15172fb 100644
--- a/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreTests.cs
+++ b/dotnet/src/Connectors/Connectors.AzureAISearch.UnitTests/AzureAISearchVectorStoreTests.cs
@@ -32,6 +32,7 @@ public AzureAISearchVectorStoreTests()
this._searchClientMock = new Mock(MockBehavior.Strict);
this._searchIndexClientMock = new Mock(MockBehavior.Strict);
this._searchIndexClientMock.Setup(x => x.GetSearchClient(TestCollectionName)).Returns(this._searchClientMock.Object);
+ this._searchIndexClientMock.Setup(x => x.ServiceName).Returns("TestService");
}
[Fact]
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchConstants.cs b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchConstants.cs
index 75ceb3b8a632..0ae13cf923ab 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchConstants.cs
@@ -8,6 +8,8 @@ namespace Microsoft.SemanticKernel.Connectors.AzureAISearch;
internal static class AzureAISearchConstants
{
+ internal const string VectorStoreSystemName = "azure.aisearch";
+
/// A set of types that a key on the provided model may have.
private static readonly HashSet s_supportedKeyTypes = [typeof(string)];
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStore.cs
index 409c36d1e05a..b270d699b6ec 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStore.cs
@@ -19,8 +19,8 @@ namespace Microsoft.SemanticKernel.Connectors.AzureAISearch;
///
public class AzureAISearchVectorStore : IVectorStore
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "AzureAISearch";
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
/// Azure AI Search client that can be used to manage the list of indices in an Azure AI Search Service.
private readonly SearchIndexClient _searchIndexClient;
@@ -39,6 +39,12 @@ public AzureAISearchVectorStore(SearchIndexClient searchIndexClient, AzureAISear
this._searchIndexClient = searchIndexClient;
this._options = options ?? new AzureAISearchVectorStoreOptions();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = AzureAISearchConstants.VectorStoreSystemName,
+ VectorStoreName = searchIndexClient.ServiceName
+ };
}
///
@@ -83,6 +89,19 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(SearchIndexClient) ? this._searchIndexClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Helper method to get the next index name from the enumerator with a try catch around the move next call to convert
/// any to , since try catch is not supported
@@ -90,7 +109,8 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
///
/// The enumerator to get the next result from.
/// A value indicating whether there are more results and the current string if true.
- private static async Task<(string name, bool more)> GetNextIndexNameAsync(ConfiguredCancelableAsyncEnumerable.Enumerator enumerator)
+ private static async Task<(string name, bool more)> GetNextIndexNameAsync(
+ ConfiguredCancelableAsyncEnumerable.Enumerator enumerator)
{
const string OperationName = "GetIndexNames";
@@ -103,7 +123,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureAISearchConstants.VectorStoreSystemName,
OperationName = OperationName
};
}
@@ -111,7 +131,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureAISearchConstants.VectorStoreSystemName,
OperationName = OperationName
};
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStoreRecordCollection.cs
index 5d9b8ddc9269..daed4951624a 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureAISearch/AzureAISearchVectorStoreRecordCollection.cs
@@ -30,8 +30,8 @@ public class AzureAISearchVectorStoreRecordCollection :
IKeywordHybridSearch
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "AzureAISearch";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
/// The default options for vector search.
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
@@ -95,7 +95,13 @@ public AzureAISearchVectorStoreRecordCollection(SearchIndexClient searchIndexCli
{
this._mapper = new AzureAISearchGenericDataModelMapper(this._model) as IVectorStoreRecordMapper;
}
-#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = AzureAISearchConstants.VectorStoreSystemName,
+ VectorStoreName = searchIndexClient.ServiceName,
+ CollectionName = collectionName
+ };
}
///
@@ -117,7 +123,7 @@ public virtual async Task CollectionExistsAsync(CancellationToken cancella
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureAISearchConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = "GetIndex"
};
@@ -462,6 +468,20 @@ public Task> HybridSearchAsync(TVector vec
return this.SearchAndMapToDataModelAsync(keywordsCombined, searchOptions, internalOptions.IncludeVectors, cancellationToken);
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(SearchIndexClient) ? this._searchIndexClient :
+ serviceType == typeof(SearchClient) ? this._searchClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Get the document with the given key and map it to the data model using the configured mapper type.
///
@@ -491,7 +511,7 @@ public Task> HybridSearchAsync(TVector vec
}
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureAISearchConstants.VectorStoreSystemName,
this._collectionName,
OperationName,
() => this._mapper!.MapFromStorageToDataModel(jsonObject, new() { IncludeVectors = includeVectors }));
@@ -554,7 +574,7 @@ private Task> MapToStorageModelAndUploadDocumentA
if (this._mapper is not null)
{
var jsonObjects = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureAISearchConstants.VectorStoreSystemName!,
this._collectionName,
OperationName,
() => records.Select(this._mapper!.MapFromDataToStorageModel));
@@ -582,7 +602,7 @@ private async IAsyncEnumerable> MapSearchResultsAsyn
await foreach (var result in results.ConfigureAwait(false))
{
var document = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureAISearchConstants.VectorStoreSystemName,
this._collectionName,
operationName,
() => this._mapper!.MapFromStorageToDataModel(result.Document, new() { IncludeVectors = includeVectors }));
@@ -666,7 +686,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureAISearchConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
@@ -675,7 +695,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureAISearchConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBConstants.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBConstants.cs
new file mode 100644
index 000000000000..b6a003c3e548
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBConstants.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.SemanticKernel.Connectors.AzureCosmosDBMongoDB;
+
+internal static class AzureCosmosDBMongoDBConstants
+{
+ public const string VectorStoreSystemName = "azure.cosmosdbmongodb";
+}
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStore.cs
index 76dc9e8500a4..7a94c003a28c 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStore.cs
@@ -17,6 +17,9 @@ namespace Microsoft.SemanticKernel.Connectors.AzureCosmosDBMongoDB;
///
public class AzureCosmosDBMongoDBVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// that can be used to manage the collections in Azure CosmosDB MongoDB.
private readonly IMongoDatabase _mongoDatabase;
@@ -34,6 +37,12 @@ public AzureCosmosDBMongoDBVectorStore(IMongoDatabase mongoDatabase, AzureCosmos
this._mongoDatabase = mongoDatabase;
this._options = options ?? new();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
+ VectorStoreName = mongoDatabase.DatabaseNamespace?.DatabaseName
+ };
}
///
@@ -75,4 +84,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(IMongoDatabase) ? this._mongoDatabase :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStoreRecordCollection.cs
index 1bf8c8b9110b..2a48e74ecea3 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBMongoDB/AzureCosmosDBMongoDBVectorStoreRecordCollection.cs
@@ -26,8 +26,8 @@ namespace Microsoft.SemanticKernel.Connectors.AzureCosmosDBMongoDB;
public class AzureCosmosDBMongoDBVectorStoreRecordCollection : IVectorStoreRecordCollection
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "AzureCosmosDBMongoDB";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
/// Property name to be used for search similarity score value.
private const string ScorePropertyName = "similarityScore";
@@ -80,6 +80,13 @@ public AzureCosmosDBMongoDBVectorStoreRecordCollection(
this._options = options ?? new AzureCosmosDBMongoDBVectorStoreRecordCollectionOptions();
this._model = new MongoDBModelBuilder().Build(typeof(TRecord), this._options.VectorStoreRecordDefinition);
this._mapper = this.InitializeMapper();
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
+ VectorStoreName = mongoDatabase.DatabaseNamespace?.DatabaseName,
+ CollectionName = collectionName
+ };
}
///
@@ -95,7 +102,7 @@ public virtual async Task CreateCollectionAsync(CancellationToken cancellationTo
{
throw new VectorStoreOperationException("Collection already exists.")
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = "CreateCollection"
};
@@ -160,7 +167,7 @@ public virtual Task DeleteCollectionAsync(CancellationToken cancellationToken =
}
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(record, new() { IncludeVectors = includeVectors }));
@@ -187,7 +194,7 @@ public virtual async IAsyncEnumerable GetAsync(
if (record is not null)
{
yield return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(record, new()));
@@ -205,7 +212,7 @@ public virtual Task UpsertAsync(TRecord record, CancellationToken cancel
var replaceOptions = new ReplaceOptions { IsUpsert = true };
var storageModel = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -310,6 +317,20 @@ public virtual async Task> VectorizedSearchAsync(this.EnumerateAndMapSearchResultsAsync(cursor, searchOptions, cancellationToken));
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(IMongoDatabase) ? this._mongoDatabase :
+ serviceType == typeof(IMongoCollection) ? this._mongoCollection :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
#region private
private async Task CreateIndexesAsync(string collectionName, CancellationToken cancellationToken)
@@ -383,7 +404,7 @@ private async IAsyncEnumerable> EnumerateAndMapSearc
{
var score = response[ScorePropertyName].AsDouble;
var record = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(response[DocumentPropertyName].AsBsonDocument, new()));
@@ -422,7 +443,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -439,7 +460,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureCosmosDBMongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLConstants.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLConstants.cs
index 6dbb0d440b45..f667488e7fd9 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLConstants.cs
@@ -4,6 +4,8 @@ namespace Microsoft.SemanticKernel.Connectors.AzureCosmosDBNoSQL;
internal static class AzureCosmosDBNoSQLConstants
{
+ internal const string VectorStoreSystemName = "azure.cosmosdbnosql";
+
///
/// Reserved key property name in Azure CosmosDB NoSQL.
///
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStore.cs
index 39320e0a8ae2..0f1cc01c4b29 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStore.cs
@@ -17,6 +17,9 @@ namespace Microsoft.SemanticKernel.Connectors.AzureCosmosDBNoSQL;
///
public class AzureCosmosDBNoSQLVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// that can be used to manage the collections in Azure CosmosDB NoSQL.
private readonly Database _database;
@@ -34,6 +37,12 @@ public AzureCosmosDBNoSQLVectorStore(Database database, AzureCosmosDBNoSQLVector
this._database = database;
this._options = options ?? new();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
+ VectorStoreName = database.Id
+ };
}
///
@@ -84,4 +93,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(Database) ? this._database :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStoreRecordCollection.cs
index 9a490a032060..d1941dc52129 100644
--- a/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.AzureCosmosDBNoSQL/AzureCosmosDBNoSQLVectorStoreRecordCollection.cs
@@ -29,8 +29,8 @@ public class AzureCosmosDBNoSQLVectorStoreRecordCollection :
IKeywordHybridSearch
#pragma warning restore CA1711 // Identifiers should not have incorrect
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "AzureCosmosDBNoSQL";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
/// The default options for vector search.
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
@@ -105,6 +105,13 @@ public AzureCosmosDBNoSQLVectorStoreRecordCollection(
// If partition key is not provided, use key property as a partition key.
this._partitionKeyProperty = this._model.KeyProperty;
}
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
+ VectorStoreName = database.Id,
+ CollectionName = collectionName
+ };
}
///
@@ -378,6 +385,19 @@ public Task> HybridSearchAsync(TVector vec
#endregion
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(Database) ? this._database :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
#region private
private void VerifyVectorType(TVector? vector)
@@ -404,7 +424,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -564,7 +584,7 @@ private async IAsyncEnumerable InternalGetAsync(
await foreach (var jsonObject in this.GetItemsAsync(queryDefinition, cancellationToken).ConfigureAwait(false))
{
yield return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(jsonObject, new() { IncludeVectors = includeVectors }));
@@ -580,7 +600,7 @@ private async Task InternalUpsertAsync(
const string OperationName = "UpsertItem";
var jsonObject = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -660,7 +680,7 @@ private async IAsyncEnumerable> MapSearchResultsAsyn
jsonObject.Remove(scorePropertyName);
var record = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ AzureCosmosDBNoSQLConstants.VectorStoreSystemName,
this.CollectionName,
operationName,
() => this._mapper.MapFromStorageToDataModel(jsonObject, new() { IncludeVectors = includeVectors }));
diff --git a/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryConstants.cs b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryConstants.cs
new file mode 100644
index 000000000000..af318ef12622
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryConstants.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.SemanticKernel.Connectors.InMemory;
+
+internal static class InMemoryConstants
+{
+ internal const string VectorStoreSystemName = "inmemory";
+}
diff --git a/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStore.cs
index 2db7013b0d27..3710cfea1dcd 100644
--- a/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStore.cs
@@ -14,6 +14,9 @@ namespace Microsoft.SemanticKernel.Connectors.InMemory;
///
public sealed class InMemoryVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// Internal storage for the record collection.
private readonly ConcurrentDictionary> _internalCollection;
@@ -26,6 +29,11 @@ public sealed class InMemoryVectorStore : IVectorStore
public InMemoryVectorStore()
{
this._internalCollection = new();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = InMemoryConstants.VectorStoreSystemName,
+ };
}
///
@@ -35,6 +43,11 @@ public InMemoryVectorStore()
internal InMemoryVectorStore(ConcurrentDictionary> internalCollection)
{
this._internalCollection = internalCollection;
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = InMemoryConstants.VectorStoreSystemName
+ };
}
///
@@ -59,4 +72,17 @@ public IAsyncEnumerable ListCollectionNamesAsync(CancellationToken cance
{
return this._internalCollection.Keys.ToAsyncEnumerable();
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(ConcurrentDictionary>) ? this._internalCollection :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStoreRecordCollection.cs
index a59501d662b1..0608ae865587 100644
--- a/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.InMemory/InMemoryVectorStoreRecordCollection.cs
@@ -23,6 +23,9 @@ public sealed class InMemoryVectorStoreRecordCollection : IVector
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
where TKey : notnull
{
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
/// The default options for vector search.
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
@@ -103,6 +106,12 @@ public InMemoryVectorStoreRecordCollection(string collectionName, InMemoryVector
return property.GetValueAsObject(record!);
};
#pragma warning restore MEVD9000 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = InMemoryConstants.VectorStoreSystemName,
+ CollectionName = collectionName
+ };
}
///
@@ -144,7 +153,7 @@ public Task CreateCollectionAsync(CancellationToken cancellationToken = default)
return Task.FromException(new VectorStoreOperationException("Collection already exists.")
{
- VectorStoreType = "InMemory",
+ VectorStoreType = InMemoryConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = "CreateCollection"
});
@@ -302,6 +311,19 @@ public async Task> VectorizedSearchAsync(T
return new VectorSearchResults(vectorSearchResultList) { TotalCount = count };
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(ConcurrentDictionary>) ? this._internalCollections :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Get the collection dictionary from the internal storage, throws if it does not exist.
///
diff --git a/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStore.cs
index 27169e3e9557..47f79724b382 100644
--- a/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStore.cs
@@ -17,6 +17,9 @@ namespace Microsoft.SemanticKernel.Connectors.MongoDB;
///
public class MongoDBVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// that can be used to manage the collections in MongoDB.
private readonly IMongoDatabase _mongoDatabase;
@@ -34,6 +37,12 @@ public MongoDBVectorStore(IMongoDatabase mongoDatabase, MongoDBVectorStoreOption
this._mongoDatabase = mongoDatabase;
this._options = options ?? new();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = MongoDBConstants.VectorStoreSystemName,
+ VectorStoreName = mongoDatabase.DatabaseNamespace?.DatabaseName
+ };
}
///
@@ -75,4 +84,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(IMongoDatabase) ? this._mongoDatabase :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStoreRecordCollection.cs
index 48f629f8aa64..8652fb70ebfc 100644
--- a/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.MongoDB/MongoDBVectorStoreRecordCollection.cs
@@ -23,8 +23,8 @@ namespace Microsoft.SemanticKernel.Connectors.MongoDB;
public class MongoDBVectorStoreRecordCollection : IVectorStoreRecordCollection, IKeywordHybridSearch
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "MongoDB";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
/// Property name to be used for search similarity score value.
private const string ScorePropertyName = "similarityScore";
@@ -80,6 +80,13 @@ public MongoDBVectorStoreRecordCollection(
this._options = options ?? new MongoDBVectorStoreRecordCollectionOptions();
this._model = new MongoDBModelBuilder().Build(typeof(TRecord), this._options.VectorStoreRecordDefinition);
this._mapper = this.InitializeMapper();
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = MongoDBConstants.VectorStoreSystemName,
+ VectorStoreName = mongoDatabase.DatabaseNamespace?.DatabaseName,
+ CollectionName = collectionName
+ };
}
///
@@ -95,7 +102,7 @@ public virtual async Task CreateCollectionAsync(CancellationToken cancellationTo
{
throw new VectorStoreOperationException("Collection already exists.")
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = MongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = "CreateCollection"
};
@@ -166,7 +173,7 @@ public virtual Task DeleteCollectionAsync(CancellationToken cancellationToken =
}
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ MongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(record, new() { IncludeVectors = includeVectors }));
@@ -193,7 +200,7 @@ public virtual async IAsyncEnumerable GetAsync(
if (record is not null)
{
yield return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ MongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(record, new()));
@@ -211,7 +218,7 @@ public virtual Task UpsertAsync(TRecord record, CancellationToken cancel
var replaceOptions = new ReplaceOptions { IsUpsert = true };
var storageModel = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ MongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -358,6 +365,20 @@ public async Task> HybridSearchAsync(TVect
cancellationToken).ConfigureAwait(false);
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(IMongoDatabase) ? this._mongoDatabase :
+ serviceType == typeof(IMongoCollection) ? this._mongoCollection :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
#region private
private async Task CreateIndexesAsync(string collectionName, CancellationToken cancellationToken)
@@ -468,7 +489,7 @@ private async IAsyncEnumerable> EnumerateAndMapSearc
{
var score = response[ScorePropertyName].AsDouble;
var record = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ MongoDBConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(response[DocumentPropertyName].AsBsonDocument, new() { IncludeVectors = includeVectors }));
@@ -507,7 +528,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = MongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -524,7 +545,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = MongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -555,7 +576,7 @@ private async Task RunOperationWithRetryAsync(
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = MongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -589,7 +610,7 @@ private async Task RunOperationWithRetryAsync(
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = MongoDBConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeConstants.cs
new file mode 100644
index 000000000000..a8b4cfadfed2
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeConstants.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.SemanticKernel.Connectors.Pinecone;
+
+internal static class PineconeConstants
+{
+ internal const string VectorStoreSystemName = "pinecone";
+}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStore.cs
index a072ea6e7336..7e8da0194443 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStore.cs
@@ -18,11 +18,12 @@ namespace Microsoft.SemanticKernel.Connectors.Pinecone;
///
public class PineconeVectorStore : IVectorStore
{
- private const string DatabaseName = "Pinecone";
-
private readonly Sdk.PineconeClient _pineconeClient;
private readonly PineconeVectorStoreOptions _options;
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
///
/// Initializes a new instance of the class.
///
@@ -34,6 +35,11 @@ public PineconeVectorStore(Sdk.PineconeClient pineconeClient, PineconeVectorStor
this._pineconeClient = pineconeClient;
this._options = options ?? new PineconeVectorStoreOptions();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = PineconeConstants.VectorStoreSystemName
+ };
}
///
@@ -71,7 +77,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = PineconeConstants.VectorStoreSystemName,
OperationName = "ListCollections"
};
}
@@ -84,4 +90,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(Sdk.PineconeClient) ? this._pineconeClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStoreRecordCollection.cs
index 43c744d1d47d..201bf69cb3fe 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Pinecone/PineconeVectorStoreRecordCollection.cs
@@ -22,10 +22,11 @@ namespace Microsoft.SemanticKernel.Connectors.Pinecone;
public class PineconeVectorStoreRecordCollection : IVectorStoreRecordCollection
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
- private const string DatabaseName = "Pinecone";
-
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
private readonly Sdk.PineconeClient _pineconeClient;
private readonly PineconeVectorStoreRecordCollectionOptions _options;
private readonly VectorStoreRecordModel _model;
@@ -59,6 +60,12 @@ public PineconeVectorStoreRecordCollection(Sdk.PineconeClient pineconeClient, st
#pragma warning disable CS0618 // IVectorStoreRecordMapper is obsolete
this._mapper = this._options.VectorCustomMapper ?? new PineconeVectorStoreRecordMapper(this._model);
#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = PineconeConstants.VectorStoreSystemName,
+ CollectionName = collectionName
+ };
}
///
@@ -134,7 +141,7 @@ public virtual async Task DeleteCollectionAsync(CancellationToken cancellationTo
{
throw new VectorStoreOperationException("Call to vector store failed.", other)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = PineconeConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = "DeleteCollection"
};
@@ -164,7 +171,7 @@ public virtual async Task DeleteCollectionAsync(CancellationToken cancellationTo
StorageToDataModelMapperOptions mapperOptions = new() { IncludeVectors = options?.IncludeVectors is true };
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ PineconeConstants.VectorStoreSystemName,
this.CollectionName,
"Get",
() => this._mapper.MapFromStorageToDataModel(result, mapperOptions));
@@ -200,7 +207,7 @@ public virtual async IAsyncEnumerable GetAsync(
StorageToDataModelMapperOptions mapperOptions = new() { IncludeVectors = options?.IncludeVectors is true };
var records = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ PineconeConstants.VectorStoreSystemName,
this.CollectionName,
"GetBatch",
() => response.Vectors.Values.Select(x => this._mapper.MapFromStorageToDataModel(x, mapperOptions)));
@@ -255,7 +262,7 @@ public virtual async Task UpsertAsync(TRecord record, CancellationToken
Verify.NotNull(record);
var vector = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ PineconeConstants.VectorStoreSystemName,
this.CollectionName,
"Upsert",
() => this._mapper.MapFromDataToStorageModel(record));
@@ -279,7 +286,7 @@ public virtual async IAsyncEnumerable UpsertAsync(IEnumerable r
Verify.NotNull(records);
var vectors = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ PineconeConstants.VectorStoreSystemName,
this.CollectionName,
"UpsertBatch",
() => records.Select(this._mapper.MapFromDataToStorageModel).ToList());
@@ -354,7 +361,7 @@ public virtual async Task> VectorizedSearchAsync skippedResults.Select(x => new VectorSearchResult(this._mapper.MapFromStorageToDataModel(new Sdk.Vector()
@@ -369,6 +376,19 @@ public virtual async Task> VectorizedSearchAsync
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(Sdk.PineconeClient) ? this._pineconeClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
private async Task RunIndexOperationAsync(string operationName, Func> operation)
{
try
@@ -387,7 +407,7 @@ private async Task RunIndexOperationAsync(string operationName, Func RunCollectionOperationAsync(string operationName, Func<
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = PineconeConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/IPostgresVectorStoreDbClient.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/IPostgresVectorStoreDbClient.cs
index 20adedde23af..9b3ff9273182 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/IPostgresVectorStoreDbClient.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/IPostgresVectorStoreDbClient.cs
@@ -22,6 +22,11 @@ internal interface IPostgresVectorStoreDbClient
///
NpgsqlDataSource DataSource { get; }
+ ///
+ /// The name of the database.
+ ///
+ string? DatabaseName { get; }
+
///
/// Check if a table exists.
///
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresConstants.cs
index f7d490503b43..21e0f003d4eb 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresConstants.cs
@@ -9,8 +9,8 @@ namespace Microsoft.SemanticKernel.Connectors.Postgres;
internal static class PostgresConstants
{
- /// The name of this database for telemetry purposes.
- public const string DatabaseName = "Postgres";
+ /// The name of this vector store for telemetry purposes.
+ public const string VectorStoreSystemName = "postgresql";
/// Validation options.
public static readonly VectorStoreRecordModelBuildingOptions ModelBuildingOptions = new()
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStore.cs
index a1840384be84..933f61173ebe 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStore.cs
@@ -17,6 +17,9 @@ public class PostgresVectorStore : IVectorStore
private readonly NpgsqlDataSource? _dataSource;
private readonly PostgresVectorStoreOptions _options;
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
///
/// Initializes a new instance of the class.
///
@@ -27,6 +30,12 @@ public PostgresVectorStore(NpgsqlDataSource dataSource, PostgresVectorStoreOptio
this._dataSource = dataSource;
this._options = options ?? new PostgresVectorStoreOptions();
this._postgresClient = new PostgresVectorStoreDbClient(this._dataSource, this._options.Schema);
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = PostgresConstants.VectorStoreSystemName,
+ VectorStoreName = this._postgresClient.DatabaseName
+ };
}
///
@@ -38,15 +47,20 @@ internal PostgresVectorStore(IPostgresVectorStoreDbClient postgresDbClient, Post
{
this._postgresClient = postgresDbClient;
this._options = options ?? new PostgresVectorStoreOptions();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = PostgresConstants.VectorStoreSystemName,
+ VectorStoreName = this._postgresClient.DatabaseName
+ };
}
///
public virtual IAsyncEnumerable ListCollectionNamesAsync(CancellationToken cancellationToken = default)
{
- const string OperationName = "ListCollectionNames";
return PostgresVectorStoreUtils.WrapAsyncEnumerableAsync(
this._postgresClient.GetTablesAsync(cancellationToken),
- OperationName
+ "ListCollectionNames"
);
}
@@ -69,4 +83,17 @@ public virtual IVectorStoreRecordCollection GetCollection ?? throw new InvalidOperationException("Failed to cast record collection.");
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(NpgsqlDataSource) ? this._dataSource :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreDbClient.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreDbClient.cs
index fc097e848881..178f60589503 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreDbClient.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreDbClient.cs
@@ -27,10 +27,14 @@ internal class PostgresVectorStoreDbClient(NpgsqlDataSource dataSource, string s
{
private readonly string _schema = schema;
+ private readonly NpgsqlConnectionStringBuilder _connectionStringBuilder = new(dataSource.ConnectionString);
+
private IPostgresVectorStoreCollectionSqlBuilder _sqlBuilder = new PostgresVectorStoreCollectionSqlBuilder();
public NpgsqlDataSource DataSource { get; } = dataSource;
+ public string? DatabaseName => this._connectionStringBuilder.Database;
+
///
public async Task DoesTableExistsAsync(string tableName, CancellationToken cancellationToken = default)
{
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreRecordCollection.cs
index eb9eae628b67..e9b5be465ae8 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreRecordCollection.cs
@@ -25,6 +25,9 @@ public class PostgresVectorStoreRecordCollection : IVectorStoreRe
///
public string CollectionName { get; }
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
/// Postgres client that is used to interact with the database.
private readonly IPostgresVectorStoreDbClient _client;
@@ -79,6 +82,13 @@ internal PostgresVectorStoreRecordCollection(IPostgresVectorStoreDbClient client
#pragma warning disable CS0618 // IVectorStoreRecordMapper is obsolete
this._mapper = this._options.DictionaryCustomMapper ?? new PostgresVectorStoreRecordMapper(this._model);
#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = PostgresConstants.VectorStoreSystemName,
+ VectorStoreName = this._client.DatabaseName,
+ CollectionName = collectionName
+ };
}
///
@@ -123,7 +133,7 @@ public virtual Task UpsertAsync(TRecord record, CancellationToken cancella
const string OperationName = "Upsert";
var storageModel = VectorStoreErrorHandler.RunModelConversion(
- PostgresConstants.DatabaseName,
+ PostgresConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -150,7 +160,7 @@ public virtual async IAsyncEnumerable UpsertAsync(IEnumerable rec
const string OperationName = "UpsertBatch";
var storageModels = records.Select(record => VectorStoreErrorHandler.RunModelConversion(
- PostgresConstants.DatabaseName,
+ PostgresConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record))).ToList();
@@ -184,7 +194,7 @@ await this.RunOperationAsync(OperationName, () =>
if (row is null) { return default; }
return VectorStoreErrorHandler.RunModelConversion(
- PostgresConstants.DatabaseName,
+ PostgresConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(row, new() { IncludeVectors = includeVectors }));
@@ -204,7 +214,7 @@ public virtual IAsyncEnumerable GetAsync(IEnumerable keys, GetRec
this._client.GetBatchAsync(this.CollectionName, keys, this._model, includeVectors, cancellationToken)
.SelectAsync(row =>
VectorStoreErrorHandler.RunModelConversion(
- PostgresConstants.DatabaseName,
+ PostgresConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(row, new() { IncludeVectors = includeVectors })),
@@ -281,7 +291,7 @@ public virtual Task> VectorizedSearchAsync
.SelectAsync(result =>
{
var record = VectorStoreErrorHandler.RunModelConversion(
- PostgresConstants.DatabaseName,
+ PostgresConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(
@@ -295,6 +305,19 @@ public virtual Task> VectorizedSearchAsync
});
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(NpgsqlDataSource) ? this._client.DataSource :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
private Task InternalCreateCollectionAsync(bool ifNotExists, CancellationToken cancellationToken = default)
{
return this._client.CreateTableAsync(this.CollectionName, this._model, ifNotExists, cancellationToken);
@@ -310,7 +333,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = PostgresConstants.DatabaseName,
+ VectorStoreType = PostgresConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -327,7 +350,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = PostgresConstants.DatabaseName,
+ VectorStoreType = PostgresConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreUtils.cs b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreUtils.cs
index 27fa7181bdc5..c97280f7f929 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreUtils.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Postgres/PostgresVectorStoreUtils.cs
@@ -19,7 +19,10 @@ internal static class PostgresVectorStoreUtils
/// The name of the operation being performed.
/// The name of the collection being operated on.
/// An async enumerable that will throw a if an exception is thrown while iterating over the original enumerator.
- public static async IAsyncEnumerable WrapAsyncEnumerableAsync(IAsyncEnumerable asyncEnumerable, string operationName, string? collectionName = null)
+ public static async IAsyncEnumerable WrapAsyncEnumerableAsync(
+ IAsyncEnumerable asyncEnumerable,
+ string operationName,
+ string? collectionName = null)
{
var enumerator = asyncEnumerable.ConfigureAwait(false).GetAsyncEnumerator();
@@ -39,7 +42,10 @@ public static async IAsyncEnumerable WrapAsyncEnumerableAsync(IAsyncEnumer
/// The name of the operation being performed.
/// The name of the collection being operated on.
/// A value indicating whether there are more results and the current string if true.
- public static async Task<(T item, bool more)> GetNextAsync(ConfiguredCancelableAsyncEnumerable.Enumerator enumerator, string operationName, string? collectionName = null)
+ public static async Task<(T item, bool more)> GetNextAsync(
+ ConfiguredCancelableAsyncEnumerable.Enumerator enumerator,
+ string operationName,
+ string? collectionName = null)
{
try
{
@@ -50,7 +56,7 @@ public static async IAsyncEnumerable WrapAsyncEnumerableAsync(IAsyncEnumer
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = PostgresConstants.DatabaseName,
+ VectorStoreType = PostgresConstants.VectorStoreSystemName,
CollectionName = collectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantConstants.cs
new file mode 100644
index 000000000000..6e983cb76806
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantConstants.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.SemanticKernel.Connectors.Qdrant;
+
+internal static class QdrantConstants
+{
+ internal const string VectorStoreSystemName = "qdrant";
+}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStore.cs
index bfac788a7cfd..ee2f4f0ec35f 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStore.cs
@@ -18,8 +18,8 @@ namespace Microsoft.SemanticKernel.Connectors.Qdrant;
///
public class QdrantVectorStore : IVectorStore
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "Qdrant";
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
/// Qdrant client that can be used to manage the collections and points in a Qdrant store.
private readonly MockableQdrantClient _qdrantClient;
@@ -48,6 +48,11 @@ internal QdrantVectorStore(MockableQdrantClient qdrantClient, QdrantVectorStoreO
this._qdrantClient = qdrantClient;
this._options = options ?? new QdrantVectorStoreOptions();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = QdrantConstants.VectorStoreSystemName
+ };
}
///
@@ -88,7 +93,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = QdrantConstants.VectorStoreSystemName,
OperationName = "ListCollections"
};
}
@@ -98,4 +103,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
yield return collection;
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(QdrantClient) ? this._qdrantClient.QdrantClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStoreRecordCollection.cs
index df33b1e8e54a..d2a3a45b1c82 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Qdrant/QdrantVectorStoreRecordCollection.cs
@@ -26,15 +26,15 @@ public class QdrantVectorStoreRecordCollection :
IKeywordHybridSearch
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
/// The default options for vector search.
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
/// The default options for hybrid vector search.
private static readonly HybridSearchOptions s_defaultKeywordVectorizedHybridSearchOptions = new();
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "Qdrant";
-
/// The name of the upsert operation for telemetry purposes.
private const string UpsertName = "Upsert";
@@ -96,6 +96,12 @@ internal QdrantVectorStoreRecordCollection(MockableQdrantClient qdrantClient, st
#pragma warning disable CS0618 // IVectorStoreRecordMapper is obsolete
this._mapper = this._options.PointStructCustomMapper ?? new QdrantVectorStoreRecordMapper(this._model, this._options.HasNamedVectors);
#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = QdrantConstants.VectorStoreSystemName,
+ CollectionName = collectionName
+ };
}
///
@@ -318,7 +324,7 @@ public virtual async Task UpsertAsync(TRecord record, CancellationToken c
// Create point from record.
var pointStruct = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
UpsertName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -337,7 +343,7 @@ async Task IVectorStoreRecordCollection.UpsertAsync(TRecord
// Create point from record.
var pointStruct = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
UpsertName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -356,7 +362,7 @@ public virtual async IAsyncEnumerable UpsertAsync(IEnumerable re
// Create points from records.
var pointStructs = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
UpsertName,
() => records.Select(this._mapper.MapFromDataToStorageModel).ToList());
@@ -379,7 +385,7 @@ async IAsyncEnumerable IVectorStoreRecordCollection.UpsertA
// Create points from records.
var pointStructs = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
UpsertName,
() => records.Select(this._mapper.MapFromDataToStorageModel).ToList());
@@ -437,7 +443,7 @@ private async IAsyncEnumerable GetBatchByPointIdAsync(
}
yield return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(pointStruct, new() { IncludeVectors = includeVectors }));
@@ -492,7 +498,7 @@ public virtual async Task> VectorizedSearchAsync> HybridSearchAsync(TVect
point,
this._mapper,
internalOptions.IncludeVectors,
- DatabaseName,
+ QdrantConstants.VectorStoreSystemName,
this._collectionName,
"Query"));
return new VectorSearchResults(mappedResults.ToAsyncEnumerable());
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(QdrantClient) ? this._qdrantClient.QdrantClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Run the given operation and wrap any with ."/>
///
@@ -600,7 +619,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = QdrantConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
@@ -624,7 +643,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = QdrantConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisConstants.cs
new file mode 100644
index 000000000000..8d3e442ff671
--- /dev/null
+++ b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisConstants.cs
@@ -0,0 +1,8 @@
+// Copyright (c) Microsoft. All rights reserved.
+
+namespace Microsoft.SemanticKernel.Connectors.Redis;
+
+internal static class RedisConstants
+{
+ internal const string VectorStoreSystemName = "redis";
+}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisHashSetVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisHashSetVectorStoreRecordCollection.cs
index 656f490c1640..4929c4bb052f 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisHashSetVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisHashSetVectorStoreRecordCollection.cs
@@ -23,8 +23,8 @@ namespace Microsoft.SemanticKernel.Connectors.Redis;
public class RedisHashSetVectorStoreRecordCollection : IVectorStoreRecordCollection
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "Redis";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
internal static readonly VectorStoreRecordModelBuildingOptions ModelBuildingOptions = new()
{
@@ -113,6 +113,13 @@ public RedisHashSetVectorStoreRecordCollection(IDatabase database, string collec
#pragma warning disable CS0618 // IVectorStoreRecordMapper is obsolete
this._mapper = this._options.HashEntriesCustomMapper ?? new RedisHashSetVectorStoreRecordMapper(this._model);
#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = RedisConstants.VectorStoreSystemName,
+ VectorStoreName = database.Database.ToString(),
+ CollectionName = collectionName
+ };
}
///
@@ -134,7 +141,7 @@ public virtual async Task CollectionExistsAsync(CancellationToken cancella
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = "FT.INFO"
};
@@ -223,7 +230,7 @@ await this.RunOperationAsync("FT.DROPINDEX",
// Convert to the caller's data model.
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
operationName,
() =>
@@ -281,7 +288,7 @@ public virtual async Task UpsertAsync(TRecord record, CancellationToken
// Map.
var redisHashSetRecord = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
"HSET",
() => this._mapper.MapFromDataToStorageModel(record));
@@ -351,7 +358,7 @@ public virtual async Task> VectorizedSearchAsync
@@ -370,6 +377,19 @@ public virtual async Task> VectorizedSearchAsync(mappedResults.ToAsyncEnumerable());
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(IDatabase) ? this._database :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Prefix the key with the collection name if the option is set.
///
@@ -419,7 +439,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
@@ -442,7 +462,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisJsonVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisJsonVectorStoreRecordCollection.cs
index c1a1d283985f..7c3631aab808 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisJsonVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisJsonVectorStoreRecordCollection.cs
@@ -26,6 +26,9 @@ namespace Microsoft.SemanticKernel.Connectors.Redis;
public class RedisJsonVectorStoreRecordCollection : IVectorStoreRecordCollection
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
internal static readonly VectorStoreRecordModelBuildingOptions ModelBuildingOptions = new()
{
RequiresAtLeastOneVector = false,
@@ -48,9 +51,6 @@ public class RedisJsonVectorStoreRecordCollection : IVectorStoreRecordC
typeof(ReadOnlyMemory?)
];
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "Redis";
-
/// The default options for vector search.
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
@@ -121,6 +121,13 @@ public RedisJsonVectorStoreRecordCollection(IDatabase database, string collectio
this._mapper = new RedisJsonVectorStoreRecordMapper(this._model.KeyProperty, this._jsonSerializerOptions);
}
#pragma warning restore CS0618
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = RedisConstants.VectorStoreSystemName,
+ VectorStoreName = database.Database.ToString(),
+ CollectionName = collectionName
+ };
}
///
@@ -142,7 +149,7 @@ public virtual async Task CollectionExistsAsync(CancellationToken cancella
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = "FT.INFO"
};
@@ -231,7 +238,7 @@ await this.RunOperationAsync("FT.DROPINDEX",
// Convert to the caller's data model.
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
"GET",
() =>
@@ -280,7 +287,7 @@ public virtual async IAsyncEnumerable GetAsync(IEnumerable keys
// Convert to the caller's data model.
yield return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
"MGET",
() =>
@@ -324,7 +331,7 @@ public virtual async Task UpsertAsync(TRecord record, CancellationToken
// Map.
var redisJsonRecord = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
"SET",
() =>
@@ -358,7 +365,7 @@ public virtual async IAsyncEnumerable UpsertAsync(IEnumerable r
foreach (var record in records)
{
var redisJsonRecord = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ RedisConstants.VectorStoreSystemName,
this._collectionName,
"MSET",
() =>
@@ -416,7 +423,7 @@ public virtual async Task> VectorizedSearchAsync
@@ -438,6 +445,19 @@ public virtual async Task> VectorizedSearchAsync(mappedResults.ToAsyncEnumerable());
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(IDatabase) ? this._database :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
///
/// Prefix the key with the collection name if the option is set.
///
@@ -486,7 +506,7 @@ private async Task RunOperationAsync(string operationName, Func operation)
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
@@ -510,7 +530,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
CollectionName = this._collectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisVectorStore.cs
index 4966917d3990..7deae3f65867 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Redis/RedisVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Redis/RedisVectorStore.cs
@@ -18,8 +18,8 @@ namespace Microsoft.SemanticKernel.Connectors.Redis;
///
public class RedisVectorStore : IVectorStore
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "Redis";
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
/// The redis database to read/write indices from.
private readonly IDatabase _database;
@@ -38,6 +38,12 @@ public RedisVectorStore(IDatabase database, RedisVectorStoreOptions? options = d
this._database = database;
this._options = options ?? new RedisVectorStoreOptions();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = RedisConstants.VectorStoreSystemName,
+ VectorStoreName = database.Database.ToString()
+ };
}
///
@@ -82,7 +88,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = RedisConstants.VectorStoreSystemName,
OperationName = OperationName
};
}
@@ -96,4 +102,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(IDatabase) ? this._metadata :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.SqlServer/ExceptionWrapper.cs b/dotnet/src/Connectors/Connectors.Memory.SqlServer/ExceptionWrapper.cs
index 6690f1d564a4..f24b4a350993 100644
--- a/dotnet/src/Connectors/Connectors.Memory.SqlServer/ExceptionWrapper.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.SqlServer/ExceptionWrapper.cs
@@ -12,8 +12,6 @@ namespace Microsoft.SemanticKernel.Connectors.SqlServer;
internal static class ExceptionWrapper
{
- internal const string VectorStoreType = "SqlServer";
-
internal static async Task WrapAsync(
SqlConnection connection,
SqlCommand command,
@@ -42,7 +40,7 @@ internal static async Task WrapAsync(
throw new VectorStoreOperationException(ex.Message, ex)
{
OperationName = operationName,
- VectorStoreType = VectorStoreType,
+ VectorStoreType = SqlServerConstants.VectorStoreSystemName,
CollectionName = collectionName
};
}
@@ -63,7 +61,7 @@ internal static async Task WrapReadAsync(
throw new VectorStoreOperationException(ex.Message, ex)
{
OperationName = operationName,
- VectorStoreType = VectorStoreType,
+ VectorStoreType = SqlServerConstants.VectorStoreSystemName,
CollectionName = collectionName
};
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerConstants.cs b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerConstants.cs
index eed61838df81..f74de4a8fcb5 100644
--- a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerConstants.cs
@@ -8,6 +8,8 @@ namespace Microsoft.SemanticKernel.Connectors.SqlServer;
internal static class SqlServerConstants
{
+ internal const string VectorStoreSystemName = "microsoft.sql_server";
+
// The actual number is actually higher (2_100), but we want to avoid any kind of "off by one" errors.
internal const int MaxParameterCount = 2_000;
diff --git a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStore.cs
index d9481ffc467d..b8517a49baba 100644
--- a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStore.cs
@@ -1,5 +1,6 @@
// Copyright (c) Microsoft. All rights reserved.
+using System;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
using System.Threading;
@@ -16,6 +17,9 @@ public sealed class SqlServerVectorStore : IVectorStore
private readonly string _connectionString;
private readonly SqlServerVectorStoreOptions _options;
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
///
/// Initializes a new instance of the class.
///
@@ -31,6 +35,14 @@ public SqlServerVectorStore(string connectionString, SqlServerVectorStoreOptions
this._options = options is not null
? new() { Schema = options.Schema }
: SqlServerVectorStoreOptions.Defaults;
+
+ var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = SqlServerConstants.VectorStoreSystemName,
+ VectorStoreName = connectionStringBuilder.InitialCatalog
+ };
}
///
@@ -63,4 +75,16 @@ public async IAsyncEnumerable ListCollectionNamesAsync([EnumeratorCancel
yield return reader.GetString(reader.GetOrdinal("table_name"));
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStoreRecordCollection.cs
index 991020d0647d..adb2a6b8b834 100644
--- a/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.SqlServer/SqlServerVectorStoreRecordCollection.cs
@@ -20,6 +20,9 @@ public sealed class SqlServerVectorStoreRecordCollection
#pragma warning restore CA1711
: IVectorStoreRecordCollection where TKey : notnull
{
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
private static readonly VectorSearchOptions s_defaultVectorSearchOptions = new();
private static readonly SqlServerVectorStoreRecordCollectionOptions s_defaultOptions = new();
@@ -60,9 +63,17 @@ public SqlServerVectorStoreRecordCollection(
Mapper = options.Mapper,
RecordDefinition = options.RecordDefinition,
};
-
this._mapper = this._options.Mapper ?? new RecordMapper(this._model);
#pragma warning restore CS0618
+
+ var connectionStringBuilder = new SqlConnectionStringBuilder(connectionString);
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = SqlServerConstants.VectorStoreSystemName,
+ VectorStoreName = connectionStringBuilder.InitialCatalog,
+ CollectionName = name
+ };
}
///
@@ -205,7 +216,7 @@ public async Task DeleteAsync(IEnumerable keys, CancellationToken cancella
throw new VectorStoreOperationException(ex.Message, ex)
{
OperationName = "DeleteBatch",
- VectorStoreType = ExceptionWrapper.VectorStoreType,
+ VectorStoreType = SqlServerConstants.VectorStoreSystemName,
CollectionName = this.CollectionName
};
}
@@ -377,7 +388,7 @@ public async IAsyncEnumerable UpsertAsync(IEnumerable records,
throw new VectorStoreOperationException(ex.Message, ex)
{
OperationName = "UpsertBatch",
- VectorStoreType = ExceptionWrapper.VectorStoreType,
+ VectorStoreType = SqlServerConstants.VectorStoreSystemName,
CollectionName = this.CollectionName
};
}
@@ -444,6 +455,18 @@ public async Task> VectorizedSearchAsync(T
}, cancellationToken, "VectorizedSearch", this.CollectionName).ConfigureAwait(false);
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
private async IAsyncEnumerable> ReadVectorSearchResultsAsync(
SqlConnection connection,
SqlCommand command,
diff --git a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteConstants.cs
index 5bcd273203a9..9c40b2668062 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteConstants.cs
@@ -8,6 +8,8 @@ namespace Microsoft.SemanticKernel.Connectors.Sqlite;
internal static class SqliteConstants
{
+ internal const string VectorStoreSystemName = "sqlite";
+
///
/// SQLite extension name for vector search.
/// More information here: .
diff --git a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStore.cs
index f5b9615884ff..6e1e5d7bc9ea 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStore.cs
@@ -18,6 +18,9 @@ namespace Microsoft.SemanticKernel.Connectors.Sqlite;
///
public class SqliteVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// The connection string for the SQLite database represented by this .
private readonly string _connectionString;
@@ -35,6 +38,14 @@ public SqliteVectorStore(string connectionString, SqliteVectorStoreOptions? opti
this._connectionString = connectionString;
this._options = options ?? new();
+
+ var connectionStringBuilder = new SqliteConnectionStringBuilder(connectionString);
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = SqliteConstants.VectorStoreSystemName,
+ VectorStoreName = connectionStringBuilder.DataSource
+ };
}
///
@@ -100,4 +111,16 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
yield return reader.GetString(ordinal);
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStoreRecordCollection.cs
index 25cd0c07da7a..28e88f7febe0 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Sqlite/SqliteVectorStoreRecordCollection.cs
@@ -24,8 +24,8 @@ public class SqliteVectorStoreRecordCollection :
IVectorStoreRecordCollection
#pragma warning restore CA1711 // Identifiers should not have incorrect
{
- /// The name of this database for telemetry purposes.
- private const string DatabaseName = "SQLite";
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
/// The connection string for the SQLite database represented by this .
private readonly string _connectionString;
@@ -131,10 +131,18 @@ public SqliteVectorStoreRecordCollection(
throw new UnreachableException();
}
}
-
#pragma warning disable CS0618 // IVectorStoreRecordMapper is obsolete
this._mapper = this._options.DictionaryCustomMapper ?? new SqliteVectorStoreRecordMapper(this._model);
#pragma warning restore CS0618
+
+ var connectionStringBuilder = new SqliteConnectionStringBuilder(connectionString);
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = SqliteConstants.VectorStoreSystemName,
+ VectorStoreName = connectionStringBuilder.DataSource,
+ CollectionName = collectionName
+ };
}
///
@@ -362,6 +370,18 @@ public async Task DeleteAsync(IEnumerable keys, CancellationToken cancel
#endregion
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
#region private
private async ValueTask GetConnectionAsync(CancellationToken cancellationToken = default)
@@ -567,7 +587,7 @@ private async Task InternalUpsertAsync(SqliteConnection connection,
const string OperationName = "Upsert";
var storageModel = VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ SqliteConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record));
@@ -590,7 +610,7 @@ private IAsyncEnumerable InternalUpsertBatchAsync(SqliteConnection c
const string OperationName = "UpsertBatch";
var storageModels = records.Select(record => VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ SqliteConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record))).ToList();
@@ -720,7 +740,7 @@ private TRecord GetAndMapRecord(
}
return VectorStoreErrorHandler.RunModelConversion(
- DatabaseName,
+ SqliteConstants.VectorStoreSystemName,
this.CollectionName,
operationName,
() => this._mapper.MapFromStorageToDataModel(storageModel, new() { IncludeVectors = includeVectors }));
@@ -736,7 +756,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = DatabaseName,
+ VectorStoreType = SqliteConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateConstants.cs b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateConstants.cs
index 3bb4b18c8991..f98b4ec35fde 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateConstants.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateConstants.cs
@@ -4,8 +4,8 @@ namespace Microsoft.SemanticKernel.Connectors.Weaviate;
internal sealed class WeaviateConstants
{
- /// The name of this database for telemetry purposes.
- public const string DatabaseName = "Weaviate";
+ /// The name of this vector store for telemetry purposes.
+ public const string VectorStoreSystemName = "weaviate";
/// Reserved key property name in Weaviate.
internal const string ReservedKeyPropertyName = "id";
diff --git a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStore.cs b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStore.cs
index 6df456e872b2..91a2944d7658 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStore.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStore.cs
@@ -18,6 +18,9 @@ namespace Microsoft.SemanticKernel.Connectors.Weaviate;
///
public class WeaviateVectorStore : IVectorStore
{
+ /// Metadata about vector store.
+ private readonly VectorStoreMetadata _metadata;
+
/// that is used to interact with Weaviate API.
private readonly HttpClient _httpClient;
@@ -39,6 +42,11 @@ public WeaviateVectorStore(HttpClient httpClient, WeaviateVectorStoreOptions? op
this._httpClient = httpClient;
this._options = options ?? new();
+
+ this._metadata = new()
+ {
+ VectorStoreSystemName = WeaviateConstants.VectorStoreSystemName
+ };
}
///
@@ -91,7 +99,7 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
{
throw new VectorStoreOperationException("Call to vector store failed.", e)
{
- VectorStoreType = WeaviateConstants.DatabaseName,
+ VectorStoreType = WeaviateConstants.VectorStoreSystemName,
OperationName = "ListCollectionNames"
};
}
@@ -104,4 +112,17 @@ public virtual async IAsyncEnumerable ListCollectionNamesAsync([Enumerat
}
}
}
+
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreMetadata) ? this._metadata :
+ serviceType == typeof(HttpClient) ? this._httpClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
}
diff --git a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStoreRecordCollection.cs b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStoreRecordCollection.cs
index f50c25d8d573..e3914c5e2f13 100644
--- a/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStoreRecordCollection.cs
+++ b/dotnet/src/Connectors/Connectors.Memory.Weaviate/WeaviateVectorStoreRecordCollection.cs
@@ -24,6 +24,9 @@ namespace Microsoft.SemanticKernel.Connectors.Weaviate;
public class WeaviateVectorStoreRecordCollection : IVectorStoreRecordCollection, IKeywordHybridSearch
#pragma warning restore CA1711 // Identifiers should not have incorrect suffix
{
+ /// Metadata about vector store record collection.
+ private readonly VectorStoreRecordCollectionMetadata _collectionMetadata;
+
/// Default JSON serializer options.
private static readonly JsonSerializerOptions s_jsonSerializerOptions = new()
{
@@ -96,6 +99,12 @@ public WeaviateVectorStoreRecordCollection(
// Assign mapper.
this._mapper = this.InitializeMapper();
+
+ this._collectionMetadata = new()
+ {
+ VectorStoreSystemName = WeaviateConstants.VectorStoreSystemName,
+ CollectionName = collectionName
+ };
}
///
@@ -208,7 +217,7 @@ public virtual Task DeleteAsync(IEnumerable keys, CancellationToken cancel
}
return VectorStoreErrorHandler.RunModelConversion(
- WeaviateConstants.DatabaseName,
+ WeaviateConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromStorageToDataModel(jsonObject!, new() { IncludeVectors = includeVectors }));
@@ -250,7 +259,7 @@ public virtual async IAsyncEnumerable UpsertAsync(IEnumerable rec
var responses = await this.RunOperationAsync(OperationName, async () =>
{
var jsonObjects = records.Select(record => VectorStoreErrorHandler.RunModelConversion(
- WeaviateConstants.DatabaseName,
+ WeaviateConstants.VectorStoreSystemName,
this.CollectionName,
OperationName,
() => this._mapper.MapFromDataToStorageModel(record))).ToList();
@@ -325,6 +334,19 @@ public async Task> HybridSearchAsync(TVect
return await this.ExecuteQueryAsync(query, searchOptions.IncludeVectors, WeaviateConstants.HybridScorePropertyName, OperationName, cancellationToken).ConfigureAwait(false);
}
+ ///
+ public object? GetService(Type serviceType, object? serviceKey = null)
+ {
+ Verify.NotNull(serviceType);
+
+ return
+ serviceKey is not null ? null :
+ serviceType == typeof(VectorStoreRecordCollectionMetadata) ? this._collectionMetadata :
+ serviceType == typeof(HttpClient) ? this._httpClient :
+ serviceType.IsInstanceOfType(this) ? this :
+ null;
+ }
+
#region private
private async Task> ExecuteQueryAsync(string query, bool includeVectors, string scorePropertyName, string operationName, CancellationToken cancellationToken)
@@ -339,7 +361,7 @@ private async Task> ExecuteQueryAsync(string query,
{
throw new VectorStoreOperationException($"Error occurred during vector search. Response: {content}")
{
- VectorStoreType = WeaviateConstants.DatabaseName,
+ VectorStoreType = WeaviateConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
@@ -350,7 +372,7 @@ private async Task> ExecuteQueryAsync(string query,
var (storageModel, score) = WeaviateVectorStoreCollectionSearchMapping.MapSearchResult(result!, scorePropertyName);
var record = VectorStoreErrorHandler.RunModelConversion(
- WeaviateConstants.DatabaseName,
+ WeaviateConstants.VectorStoreSystemName,
this.CollectionName,
operationName,
() => this._mapper.MapFromStorageToDataModel(storageModel, new() { IncludeVectors = includeVectors }));
@@ -415,7 +437,7 @@ private async Task RunOperationAsync(string operationName, Func> o
{
throw new VectorStoreOperationException("Call to vector store failed.", ex)
{
- VectorStoreType = WeaviateConstants.DatabaseName,
+ VectorStoreType = WeaviateConstants.VectorStoreSystemName,
CollectionName = this.CollectionName,
OperationName = operationName
};
diff --git a/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreRecordCollectionTests.cs b/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreRecordCollectionTests.cs
index a931bbea0b67..74545d03cda3 100644
--- a/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreRecordCollectionTests.cs
+++ b/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreRecordCollectionTests.cs
@@ -22,6 +22,7 @@ public class PostgresVectorStoreRecordCollectionTests
public PostgresVectorStoreRecordCollectionTests()
{
this._postgresClientMock = new Mock(MockBehavior.Strict);
+ this._postgresClientMock.Setup(l => l.DatabaseName).Returns("TestDatabase");
}
[Fact]
diff --git a/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreTests.cs b/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreTests.cs
index 33cfc005a7bc..8a89582fc0f8 100644
--- a/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreTests.cs
+++ b/dotnet/src/Connectors/Connectors.Postgres.UnitTests/PostgresVectorStoreTests.cs
@@ -26,6 +26,7 @@ public class PostgresVectorStoreTests
public PostgresVectorStoreTests()
{
this._postgresClientMock = new Mock(MockBehavior.Strict);
+ this._postgresClientMock.Setup(l => l.DatabaseName).Returns("TestDatabase");
}
[Fact]
@@ -60,7 +61,10 @@ public void GetCollectionCallsFactoryIfProvided()
var factoryMock = new Mock(MockBehavior.Strict);
var collectionMock = new Mock>>(MockBehavior.Strict);
var clientMock = new Mock(MockBehavior.Strict);
+
clientMock.Setup(x => x.DataSource).Returns(null);
+ clientMock.Setup(x => x.DatabaseName).Returns("TestDatabase");
+
factoryMock
.Setup(x => x.CreateVectorStoreRecordCollection>(It.IsAny(), TestCollectionName, null))
.Returns(collectionMock.Object);
diff --git a/dotnet/src/Connectors/Connectors.Redis.UnitTests/RedisHashSetVectorStoreRecordCollectionTests.cs b/dotnet/src/Connectors/Connectors.Redis.UnitTests/RedisHashSetVectorStoreRecordCollectionTests.cs
index 8b4324a6a98d..e95a83321b05 100644
--- a/dotnet/src/Connectors/Connectors.Redis.UnitTests/RedisHashSetVectorStoreRecordCollectionTests.cs
+++ b/dotnet/src/Connectors/Connectors.Redis.UnitTests/RedisHashSetVectorStoreRecordCollectionTests.cs
@@ -28,6 +28,7 @@ public class RedisHashSetVectorStoreRecordCollectionTests
public RedisHashSetVectorStoreRecordCollectionTests()
{
this._redisDatabaseMock = new Mock(MockBehavior.Strict);
+ this._redisDatabaseMock.Setup(l => l.Database).Returns(0);
var batchMock = new Mock();
this._redisDatabaseMock.Setup(x => x.CreateBatch(It.IsAny