using System.Web; namespace BotSharp.Plugin.MongoStorage; public class MongoDbContext { private readonly MongoClient _mongoClient; private readonly string _mongoDbDatabaseName; private readonly string _collectionPrefix; public MongoDbContext(BotSharpDatabaseSettings dbSettings) { var mongoDbConnectionString = dbSettings.BotSharpMongoDb.ConnectionString; var dbNameIndex = dbSettings.BotSharpMongoDb.DbNameIndex; _mongoClient = new MongoClient(mongoDbConnectionString); _mongoDbDatabaseName = GetDatabaseName(mongoDbConnectionString, dbNameIndex); _collectionPrefix = dbSettings.TablePrefix.IfNullOrEmptyAs("BotSharp"); } private string GetDatabaseName(string mongoDbConnectionString, string? dbNameIndex = null) { var dbName = string.Empty; if (!Uri.TryCreate(mongoDbConnectionString, UriKind.Absolute, out var conn)) { return dbName; } var query = HttpUtility.ParseQueryString(conn.Query); var keys = query.AllKeys ?? []; if (!string.IsNullOrWhiteSpace(dbNameIndex) && keys.Contains(dbNameIndex)) { dbName = query[dbNameIndex]; } else { dbName = conn.Segments?.FirstOrDefault(x => x != "/") ?? string.Empty; } return dbName; } private IMongoDatabase Database { get { return _mongoClient.GetDatabase(_mongoDbDatabaseName); } } #region Indexes private IMongoCollection CreateConversationIndex() { var collection = Database.GetCollection($"{_collectionPrefix}_Conversations"); var indexes = collection.Indexes.List().ToList(); var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime")); if (createTimeIndex == null) { var indexDef = Builders.IndexKeys.Descending(x => x.CreatedTime); collection.Indexes.CreateOne(new CreateIndexModel(indexDef)); } return collection; } private IMongoCollection CreateConversationStateIndex() { var collection = Database.GetCollection($"{_collectionPrefix}_ConversationStates"); var indexes = collection.Indexes.List().ToList(); var stateIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("States.Key")); if (stateIndex == null) { var indexDef = Builders.IndexKeys.Ascending("States.Key"); collection.Indexes.CreateOne(new CreateIndexModel(indexDef)); } return collection; } private IMongoCollection CreateAgentTaskIndex() { var collection = Database.GetCollection($"{_collectionPrefix}_AgentTasks"); var indexes = collection.Indexes.List().ToList(); var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime")); if (createTimeIndex == null) { var indexDef = Builders.IndexKeys.Descending(x => x.CreatedTime); collection.Indexes.CreateOne(new CreateIndexModel(indexDef)); } return collection; } private IMongoCollection CreateContentLogIndex() { var collection = Database.GetCollection($"{_collectionPrefix}_ConversationContentLogs"); var indexes = collection.Indexes.List().ToList(); var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreateTime")); if (createTimeIndex == null) { var indexDef = Builders.IndexKeys.Ascending(x => x.CreateTime); collection.Indexes.CreateOne(new CreateIndexModel(indexDef)); } return collection; } private IMongoCollection CreateStateLogIndex() { var collection = Database.GetCollection($"{_collectionPrefix}_ConversationStateLogs"); var indexes = collection.Indexes.List().ToList(); var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreateTime")); if (createTimeIndex == null) { var indexDef = Builders.IndexKeys.Ascending(x => x.CreateTime); collection.Indexes.CreateOne(new CreateIndexModel(indexDef)); } return collection; } #endregion public IMongoCollection Agents => Database.GetCollection($"{_collectionPrefix}_Agents"); public IMongoCollection AgentTasks => CreateAgentTaskIndex(); public IMongoCollection Conversations => CreateConversationIndex(); public IMongoCollection ConversationDialogs => Database.GetCollection($"{_collectionPrefix}_ConversationDialogs"); public IMongoCollection ConversationStates => CreateConversationStateIndex(); public IMongoCollection ExectionLogs => Database.GetCollection($"{_collectionPrefix}_ExecutionLogs"); public IMongoCollection LlmCompletionLogs => Database.GetCollection($"{_collectionPrefix}_LlmCompletionLogs"); public IMongoCollection ContentLogs => CreateContentLogIndex(); public IMongoCollection StateLogs => CreateStateLogIndex(); public IMongoCollection Users => Database.GetCollection($"{_collectionPrefix}_Users"); public IMongoCollection UserAgents => Database.GetCollection($"{_collectionPrefix}_UserAgents"); public IMongoCollection Plugins => Database.GetCollection($"{_collectionPrefix}_Plugins"); public IMongoCollection TranslationMemories => Database.GetCollection($"{_collectionPrefix}_TranslationMemories"); }