mirror of
https://github.com/MindWorkAI/AI-Studio.git
synced 2026-10-18 04:37:59 +00:00
Show the total number of stored vectors
This commit is contained in:
2 files changed
+42
-4
No files matched your search
@@ -104,7 +104,7 @@ public sealed class DatabaseClientProvider(RustService rustService, ILoggerFacto
|
|||||||
|
|
||||||
private async Task<DatabaseClient> CreateClientAsync(DatabaseRole databaseRole, CancellationToken cancellationToken) => databaseRole switch
|
private async Task<DatabaseClient> CreateClientAsync(DatabaseRole databaseRole, CancellationToken cancellationToken) => databaseRole switch
|
||||||
{
|
{
|
||||||
DatabaseRole.VECTOR_STORE => await QdrantEdgeClientImplementation.CreateAsync(rustService, this.logger, this.databaseClientLogger, cancellationToken),
|
DatabaseRole.VECTOR_STORE => await QdrantEdgeClientImplementation.CreateAsync(rustService, this.GetIndexStoreAsync, this.logger, this.databaseClientLogger, cancellationToken),
|
||||||
DatabaseRole.INDEX_STORE => await SqliteIndexStoreClientImplementation.CreateAsync(this.logger, this.databaseClientLogger, cancellationToken),
|
DatabaseRole.INDEX_STORE => await SqliteIndexStoreClientImplementation.CreateAsync(this.logger, this.databaseClientLogger, cancellationToken),
|
||||||
_ => new NoDatabaseClient(databaseRole.ToString(), "The requested database role is not supported.")
|
_ => new NoDatabaseClient(databaseRole.ToString(), "The requested database role is not supported.")
|
||||||
};
|
};
|
||||||
|
|||||||
+41
-3
@@ -1,15 +1,26 @@
|
|||||||
|
using System.Globalization;
|
||||||
|
|
||||||
|
using AIStudio.Tools.Databases.IndexStore;
|
||||||
using AIStudio.Tools.PluginSystem;
|
using AIStudio.Tools.PluginSystem;
|
||||||
using AIStudio.Tools.Rust;
|
using AIStudio.Tools.Rust;
|
||||||
using AIStudio.Tools.Services;
|
using AIStudio.Tools.Services;
|
||||||
|
|
||||||
namespace AIStudio.Tools.Databases.VectorStore;
|
namespace AIStudio.Tools.Databases.VectorStore;
|
||||||
|
|
||||||
|
/// <param name="indexStoreAccessor">
|
||||||
|
/// Resolves the index store, which is where the number of stored vectors comes from. Counting the
|
||||||
|
/// points in Qdrant Edge itself would have to load every shard first and would hold the global
|
||||||
|
/// database mutex against ongoing inserts and searches. The accessor is only called while building
|
||||||
|
/// the display info, never while this client is created: creating it already holds the vector store
|
||||||
|
/// lock, and the accessor takes the index store lock, so the two are never held at the same time.
|
||||||
|
/// </param>
|
||||||
public sealed class QdrantEdgeClientImplementation(
|
public sealed class QdrantEdgeClientImplementation(
|
||||||
string name,
|
string name,
|
||||||
string path,
|
string path,
|
||||||
string version,
|
string version,
|
||||||
int storesCount,
|
int storesCount,
|
||||||
RustService rustService) : VectorStoreClient(name, path)
|
RustService rustService,
|
||||||
|
Func<CancellationToken, Task<IndexStoreClient>> indexStoreAccessor) : VectorStoreClient(name, path)
|
||||||
{
|
{
|
||||||
private const string DATABASE_NAME = "Qdrant Edge";
|
private const string DATABASE_NAME = "Qdrant Edge";
|
||||||
private const string INFO_PATH = "/system/qdrant-edge/info";
|
private const string INFO_PATH = "/system/qdrant-edge/info";
|
||||||
@@ -28,6 +39,7 @@ public sealed class QdrantEdgeClientImplementation(
|
|||||||
|
|
||||||
public static async Task<DatabaseClient> CreateAsync(
|
public static async Task<DatabaseClient> CreateAsync(
|
||||||
RustService rustService,
|
RustService rustService,
|
||||||
|
Func<CancellationToken, Task<IndexStoreClient>> indexStoreAccessor,
|
||||||
ILogger logger,
|
ILogger logger,
|
||||||
ILogger<DatabaseClient> databaseClientLogger,
|
ILogger<DatabaseClient> databaseClientLogger,
|
||||||
CancellationToken cancellationToken)
|
CancellationToken cancellationToken)
|
||||||
@@ -60,7 +72,7 @@ public sealed class QdrantEdgeClientImplementation(
|
|||||||
return CreateNoVectorStoreClient(DATABASE_NAME, $"Failed to get the {DATABASE_NAME} path from Rust.", DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
|
return CreateNoVectorStoreClient(DATABASE_NAME, $"Failed to get the {DATABASE_NAME} path from Rust.", DatabaseClientStatus.UNAVAILABLE, databaseClientLogger);
|
||||||
|
|
||||||
var name = string.IsNullOrWhiteSpace(qdrantEdgeInfo.Name) ? DATABASE_NAME : qdrantEdgeInfo.Name;
|
var name = string.IsNullOrWhiteSpace(qdrantEdgeInfo.Name) ? DATABASE_NAME : qdrantEdgeInfo.Name;
|
||||||
var client = new QdrantEdgeClientImplementation(name, qdrantEdgeInfo.Path, qdrantEdgeInfo.Version, qdrantEdgeInfo.StoresCount, rustService);
|
var client = new QdrantEdgeClientImplementation(name, qdrantEdgeInfo.Path, qdrantEdgeInfo.Version, qdrantEdgeInfo.StoresCount, rustService, indexStoreAccessor);
|
||||||
client.SetLogger(databaseClientLogger);
|
client.SetLogger(databaseClientLogger);
|
||||||
return client;
|
return client;
|
||||||
}
|
}
|
||||||
@@ -77,9 +89,35 @@ public sealed class QdrantEdgeClientImplementation(
|
|||||||
if (!currentInfo.IsAvailable)
|
if (!currentInfo.IsAvailable)
|
||||||
yield return (TB("Status"), currentInfo.UnavailableReason ?? TB("Qdrant Edge is not available."));
|
yield return (TB("Status"), currentInfo.UnavailableReason ?? TB("Qdrant Edge is not available."));
|
||||||
|
|
||||||
|
var storedVectors = await this.GetStoredVectorCountAsync();
|
||||||
|
|
||||||
yield return (TB("Reported version"), displayVersion);
|
yield return (TB("Reported version"), displayVersion);
|
||||||
yield return (TB("Storage size"), $"{this.GetStorageSize()}");
|
yield return (TB("Storage size"), $"{this.GetStorageSize()}");
|
||||||
yield return (TB("Number of vector stores"), displayStoresCount.ToString());
|
yield return (TB("Number of vector stores"), displayStoresCount.ToString("N0", I18N.I.Culture));
|
||||||
|
yield return (TB("Stored vectors"), storedVectors?.ToString("N0", I18N.I.Culture) ?? TB("unknown"));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Reads how many vectors the vector stores hold in total.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>The number of vectors, or null when the index store cannot tell.</returns>
|
||||||
|
private async Task<long?> GetStoredVectorCountAsync()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
//
|
||||||
|
// One chunk is one vector: every chunk becomes exactly one point carrying the single
|
||||||
|
// named vector "embedding". So the index store knows this number without Qdrant Edge
|
||||||
|
// having to load a single shard for it.
|
||||||
|
//
|
||||||
|
var indexStore = await indexStoreAccessor(CancellationToken.None);
|
||||||
|
return await indexStore.GetTotalChunkCountAsync(CancellationToken.None);
|
||||||
|
}
|
||||||
|
catch (Exception exception)
|
||||||
|
{
|
||||||
|
this.Logger?.LogWarning(exception, "Failed to read the number of stored vectors from the index store.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override async Task<VectorStoreEnsureResult> EnsureVectorStoreExists(string storeName, string dataSourceName, int vectorSize, CancellationToken token) =>
|
public override async Task<VectorStoreEnsureResult> EnsureVectorStoreExists(string storeName, string dataSourceName, int vectorSize, CancellationToken token) =>
|
||||||
|
|||||||
Reference in new issue
Block a user