首页 > 解决方案 > 检测是否将创建/已创建 MongoDb 数据库

问题描述

我们为每个租户使用一个数据库。所以我们的代码如下所示:

 var collection = MongoClient.GetDatabase(accountId).GetCollection("mycol");

在这个地方,我们不知道数据库是否已经存在。收藏也一样。

问题:我想创建一个索引。为了能够做到这一点,我需要在创建新数据库或集合时有一些“事件”,所以我知道我必须为它创建索引。

选项:

有没有办法在创建数据库或集合时获得触发器?

标签: c#mongodb

解决方案


MongoDB 与其他类似 RDBMS 的数据库之间的主要区别在于,在 MongoDB 中,数据库和集合是自动创建的。文档说:

如果数据库不存在,MongoDB 会在您首次存储该数据库的数据时创建该数据库

因此,当您尝试访问不存在的数据库时,您不会收到任何错误。此外,C# 驱动程序中没有“DatabaseExists”方法,但您可以创建自己的方法。要检查数据库是否存在,您可以使用db.stats admin 命令返回有关特定数据库的一些重要统计信息。

的示例结果db.stats可能如下所示:

{
    "db" : "databasene2",
    "collections" : 0,
    "views" : 0,
    "objects" : 0,
    "avgObjSize" : 0,
    "dataSize" : 0,
    "storageSize" : 0,
    "numExtents" : 0,
    "indexes" : 0,
    "indexSize" : 0,
    "fileSize" : 0,
    "fsUsedSize" : 0,
    "fsTotalSize" : 0,
    "ok" : 1
}

null因此,您可以在 C# 中创建一个扩展方法,如果没有集合和索引,它将返回:

public static IMongoDatabase GetDatabaseIfExists(this IMongoClient client, string databaseName)
{
    var database = client.GetDatabase(databaseName);
    var command = "{ dbStats: 1, scale: 1 }";
    var dbStats = database.RunCommand<BsonDocument>(command);
    var databaseExists = dbStats["collections"].AsInt32 > 0 || dbStats["indexes"].AsInt32 > 0;

    return databaseExists ? database : null;
}

用法:

var mongoClient = new MongoClient(settings);
var db = mongoClient.GetDatabaseIfExists("dbThatNotExists"); //returns null

同样,您可以利用collStats命令创建另一个方法,在这种情况下,MongoDB C# 驱动程序会抛出MongoCommandException,尝试:

public static IMongoCollection<T> GetCollectionIfExists<T>(this IMongoDatabase database, string collectionName)
{
    var command = $"{{ collStats: \"{collectionName}\", scale: 1 }}";
    try
    {
        database.RunCommand<BsonDocument>(command);
        return database.GetCollection<T>(collectionName);
    }
    catch(MongoCommandException e) when (e.ErrorMessage.EndsWith("not found."))
    {
        return null;
    }
}

显然,您不必每次需要访问数据库时都运行这些方法。您可以运行它们一次,然后将现有数据库名称缓存在内存中并GetDatabase直接使用。


推荐阅读