BotSharp/src/Plugins/BotSharp.Plugin.MongoStorage/MongoDbContext.cs

213 lines
8.9 KiB
C#
Raw Normal View History

using BotSharp.Abstraction.Repositories.Settings;
2023-09-01 22:33:36 +00:00
namespace BotSharp.Plugin.MongoStorage;
2023-08-26 04:41:01 +00:00
public class MongoDbContext
{
private readonly MongoClient _mongoClient;
private readonly string _mongoDbDatabaseName;
2023-09-12 22:34:50 +00:00
private readonly string _collectionPrefix;
2023-08-26 04:41:01 +00:00
2024-07-22 22:44:19 +00:00
private const string DB_NAME_INDEX = "authSource";
2023-09-12 22:34:50 +00:00
public MongoDbContext(BotSharpDatabaseSettings dbSettings)
2023-08-26 04:41:01 +00:00
{
2024-07-22 22:44:19 +00:00
var mongoDbConnectionString = dbSettings.BotSharpMongoDb;
2023-08-26 04:41:01 +00:00
_mongoClient = new MongoClient(mongoDbConnectionString);
2024-07-22 22:44:19 +00:00
_mongoDbDatabaseName = GetDatabaseName(mongoDbConnectionString);
2023-10-16 22:52:48 +00:00
_collectionPrefix = dbSettings.TablePrefix.IfNullOrEmptyAs("BotSharp");
2023-08-26 04:41:01 +00:00
}
2024-07-22 22:44:19 +00:00
private string GetDatabaseName(string mongoDbConnectionString)
2023-08-26 04:41:01 +00:00
{
2024-07-24 00:38:18 +00:00
var databaseName = mongoDbConnectionString.Substring(mongoDbConnectionString.LastIndexOf("/", StringComparison.InvariantCultureIgnoreCase) + 1);
2024-07-24 01:28:39 +00:00
var symbol = "?";
if (databaseName.Contains(symbol))
2023-08-26 04:41:01 +00:00
{
2024-07-24 01:28:39 +00:00
var markIdx = databaseName.IndexOf(symbol, StringComparison.InvariantCultureIgnoreCase);
var db = databaseName.Substring(0, markIdx);
if (!string.IsNullOrWhiteSpace(db))
{
return db;
}
var queryStr = databaseName.Substring(markIdx + 1);
2024-07-24 02:22:03 +00:00
var queries = queryStr.Split("&", StringSplitOptions.RemoveEmptyEntries).Select(x => new
2024-07-24 01:28:39 +00:00
{
Key = x.Split("=")[0],
Value = x.Split("=")[1]
}).ToList();
2024-12-12 09:09:46 +00:00
2024-07-24 01:28:39 +00:00
var source = queries.FirstOrDefault(x => x.Key.IsEqualTo(DB_NAME_INDEX));
if (source != null)
{
databaseName = source.Value;
}
2023-08-26 04:41:01 +00:00
}
2024-07-24 00:38:18 +00:00
return databaseName;
2023-08-26 04:41:01 +00:00
}
private IMongoDatabase Database => _mongoClient.GetDatabase(_mongoDbDatabaseName);
2025-02-19 17:16:51 +00:00
#region Private methods
private bool CollectionExists(IMongoDatabase database, string collectionName)
{
var filter = Builders<BsonDocument>.Filter.Eq("name", collectionName);
2025-02-19 17:16:51 +00:00
var collections = database.ListCollectionNames(new ListCollectionNamesOptions { Filter = filter }).ToList();
return collections.Any();
}
private IMongoCollection<TDocument> GetCollectionOrCreate<TDocument>(string name)
{
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentException($"The collection {name} cannot be empty.");
2025-02-19 17:16:51 +00:00
var collectionName = $"{_collectionPrefix}_{name}";
if (!CollectionExists(Database, collectionName))
2025-02-19 17:16:51 +00:00
{
Database.CreateCollection(collectionName);
2025-02-19 17:16:51 +00:00
}
var collection = Database.GetCollection<TDocument>(collectionName);
return collection;
}
2023-08-26 04:41:01 +00:00
2024-02-15 20:43:36 +00:00
#region Indexes
2024-02-14 20:15:23 +00:00
private IMongoCollection<ConversationDocument> CreateConversationIndex()
{
var collection = GetCollectionOrCreate<ConversationDocument>("Conversations");
2024-02-14 20:15:23 +00:00
var indexes = collection.Indexes.List().ToList();
var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime"));
if (createTimeIndex == null)
{
var indexDef = Builders<ConversationDocument>.IndexKeys.Descending(x => x.CreatedTime);
collection.Indexes.CreateOne(new CreateIndexModel<ConversationDocument>(indexDef));
}
return collection;
}
2024-07-09 07:34:49 +00:00
private IMongoCollection<ConversationStateDocument> CreateConversationStateIndex()
{
var collection = GetCollectionOrCreate<ConversationStateDocument>("ConversationStates");
2024-07-09 07:34:49 +00:00
var indexes = collection.Indexes.List().ToList();
var stateIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("States.Key"));
if (stateIndex == null)
{
var indexDef = Builders<ConversationStateDocument>.IndexKeys.Ascending("States.Key");
collection.Indexes.CreateOne(new CreateIndexModel<ConversationStateDocument>(indexDef));
}
return collection;
}
2024-02-14 20:15:23 +00:00
private IMongoCollection<AgentTaskDocument> CreateAgentTaskIndex()
{
var collection = GetCollectionOrCreate<AgentTaskDocument>("AgentTasks");
2024-02-14 20:15:23 +00:00
var indexes = collection.Indexes.List().ToList();
var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime"));
if (createTimeIndex == null)
{
var indexDef = Builders<AgentTaskDocument>.IndexKeys.Descending(x => x.CreatedTime);
collection.Indexes.CreateOne(new CreateIndexModel<AgentTaskDocument>(indexDef));
}
return collection;
}
2024-02-15 20:43:36 +00:00
private IMongoCollection<ConversationContentLogDocument> CreateContentLogIndex()
2024-02-14 20:15:23 +00:00
{
var collection = GetCollectionOrCreate<ConversationContentLogDocument>("ConversationContentLogs");
2024-02-15 20:43:36 +00:00
var indexes = collection.Indexes.List().ToList();
2025-03-06 23:44:49 +00:00
var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime"));
2024-02-15 20:43:36 +00:00
if (createTimeIndex == null)
2024-02-14 20:15:23 +00:00
{
var indexDef = Builders<ConversationContentLogDocument>.IndexKeys.Ascending(x => x.CreatedTime);
2024-02-15 20:43:36 +00:00
collection.Indexes.CreateOne(new CreateIndexModel<ConversationContentLogDocument>(indexDef));
2024-02-14 20:15:23 +00:00
}
2024-02-15 20:43:36 +00:00
return collection;
2024-02-14 20:15:23 +00:00
}
2024-02-04 05:42:13 +00:00
2024-02-15 20:43:36 +00:00
private IMongoCollection<ConversationStateLogDocument> CreateStateLogIndex()
2024-02-14 20:15:23 +00:00
{
var collection = GetCollectionOrCreate<ConversationStateLogDocument>("ConversationStateLogs");
2024-02-15 20:43:36 +00:00
var indexes = collection.Indexes.List().ToList();
2025-03-06 23:44:49 +00:00
var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime"));
2024-02-15 20:43:36 +00:00
if (createTimeIndex == null)
2024-02-14 20:15:23 +00:00
{
var indexDef = Builders<ConversationStateLogDocument>.IndexKeys.Ascending(x => x.CreatedTime);
2024-02-15 20:43:36 +00:00
collection.Indexes.CreateOne(new CreateIndexModel<ConversationStateLogDocument>(indexDef));
2024-02-14 20:15:23 +00:00
}
2024-02-15 20:43:36 +00:00
return collection;
2024-02-14 20:15:23 +00:00
}
2025-03-06 23:44:49 +00:00
private IMongoCollection<InstructionLogDocument> CreateInstructionLogIndex()
{
var collection = GetCollectionOrCreate<InstructionLogDocument>("InstructionLogs");
var indexes = collection.Indexes.List().ToList();
var createTimeIndex = indexes.FirstOrDefault(x => x.GetElement("name").ToString().StartsWith("CreatedTime"));
if (createTimeIndex == null)
{
var indexDef = Builders<InstructionLogDocument>.IndexKeys.Descending(x => x.CreatedTime);
collection.Indexes.CreateOne(new CreateIndexModel<InstructionLogDocument>(indexDef));
}
return collection;
}
2024-02-15 20:43:36 +00:00
#endregion
2025-02-19 17:16:51 +00:00
#endregion
2024-02-15 20:43:36 +00:00
public IMongoCollection<AgentDocument> Agents
=> GetCollectionOrCreate<AgentDocument>("Agents");
2024-02-15 20:43:36 +00:00
public IMongoCollection<AgentTaskDocument> AgentTasks
=> CreateAgentTaskIndex();
public IMongoCollection<ConversationDocument> Conversations
=> CreateConversationIndex();
2023-08-26 04:41:01 +00:00
public IMongoCollection<ConversationDialogDocument> ConversationDialogs
=> GetCollectionOrCreate<ConversationDialogDocument>("ConversationDialogs");
2023-09-06 04:41:49 +00:00
2024-01-01 04:56:10 +00:00
public IMongoCollection<ConversationStateDocument> ConversationStates
2024-07-09 07:34:49 +00:00
=> CreateConversationStateIndex();
2024-01-01 04:56:10 +00:00
2024-02-15 20:43:36 +00:00
public IMongoCollection<LlmCompletionLogDocument> LlmCompletionLogs
=> GetCollectionOrCreate<LlmCompletionLogDocument>("LlmCompletionLogs");
2024-02-15 20:43:36 +00:00
public IMongoCollection<ConversationContentLogDocument> ContentLogs
=> CreateContentLogIndex();
public IMongoCollection<ConversationStateLogDocument> StateLogs
=> CreateStateLogIndex();
public IMongoCollection<UserDocument> Users
=> GetCollectionOrCreate<UserDocument>("Users");
2023-08-26 04:41:01 +00:00
public IMongoCollection<UserAgentDocument> UserAgents
=> GetCollectionOrCreate<UserAgentDocument>("UserAgents");
2023-11-27 23:49:24 +00:00
2024-01-13 02:13:38 +00:00
public IMongoCollection<PluginDocument> Plugins
=> GetCollectionOrCreate<PluginDocument>("Plugins");
2024-06-14 22:10:25 +00:00
public IMongoCollection<TranslationMemoryDocument> TranslationMemories
=> GetCollectionOrCreate<TranslationMemoryDocument>("TranslationMemories");
2024-09-09 17:05:11 +00:00
public IMongoCollection<KnowledgeCollectionConfigDocument> KnowledgeCollectionConfigs
=> GetCollectionOrCreate<KnowledgeCollectionConfigDocument>("KnowledgeCollectionConfigs");
2024-09-17 17:50:39 +00:00
public IMongoCollection<KnowledgeCollectionFileMetaDocument> KnowledgeCollectionFileMeta
=> GetCollectionOrCreate<KnowledgeCollectionFileMetaDocument>("KnowledgeCollectionFileMeta");
2024-11-14 23:33:26 +00:00
public IMongoCollection<RoleDocument> Roles
=> GetCollectionOrCreate<RoleDocument>("Roles");
2024-11-14 23:33:26 +00:00
public IMongoCollection<RoleAgentDocument> RoleAgents
=> GetCollectionOrCreate<RoleAgentDocument>("RoleAgents");
2024-12-09 00:29:04 +00:00
public IMongoCollection<CrontabItemDocument> CrontabItems
=> GetCollectionOrCreate<CrontabItemDocument>("CronTabItems");
2024-12-12 09:09:46 +00:00
2025-05-08 16:30:40 +00:00
public IMongoCollection<GlobalStatisticsDocument> GlobalStats
=> GetCollectionOrCreate<GlobalStatisticsDocument>("GlobalStats");
2025-01-24 05:45:43 +00:00
2025-03-06 23:44:49 +00:00
public IMongoCollection<InstructionLogDocument> InstructionLogs
=> CreateInstructionLogIndex();
}