【问题标题】:How can I save entire MongoDB collection to json/bson file using C#?如何使用 C# 将整个 MongoDB 集合保存到 json/bson 文件?
【发布时间】:2015-08-07 23:25:16
【问题描述】:

我有一个过程,它首先生成大量数据,这些数据保存到 mongoDB 集合中,然后分析数据,最后 - 我想将整个集合保存到磁盘上的文件中,然后擦除集合。 我知道我可以使用 MongoDump.exe 轻松完成,但我想知道有什么方法可以直接从 c# 中完成吗? - 我的意思是不运行控制台进程 - 而是使用 MOngo C# 驱动程序中的一些功能。

而且,如果可以,我将如何在 c# 中进行反向操作? - 即:将 .bson 文件加载到集合中?

【问题讨论】:

    标签: c# json mongodb bson


    【解决方案1】:

    您可以使用以下两种方法来完成此操作:

    public static async Task WriteCollectionToFile(IMongoDatabase database, string collectionName, string fileName)
    {
        var collection = database.GetCollection<RawBsonDocument>(collectionName);
    
        // Make sure the file is empty before we start writing to it
        File.WriteAllText(fileName, string.Empty);
    
        using (var cursor = await collection.FindAsync(new BsonDocument()))
        {
            while (await cursor.MoveNextAsync())
            {
                var batch = cursor.Current;
                foreach (var document in batch)
                {
                    File.AppendAllLines(fileName, new[] { document.ToString() });
                }
            }
        }
    }
    
    public static async Task LoadCollectionFromFile(IMongoDatabase database, string collectionName, string fileName)
    {
        using (FileStream fs = File.Open(fileName, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        using (BufferedStream bs = new BufferedStream(fs))
        using (StreamReader sr = new StreamReader(bs))
        {
            var collection = database.GetCollection<BsonDocument>(collectionName);
    
            string line;
            while ((line = sr.ReadLine()) != null)
            {
                await collection.InsertOneAsync(BsonDocument.Parse(line));
            }
        }
    }
    

    以下是您如何使用它们的示例:

    // Obviously you'll need to change all these values to your environment
    var connectionString = "mongodb://localhost:27017";
    var database = new MongoClient(connectionString).GetDatabase("database");
    var fileName = @"C:\mongo_output.txt";
    var collectionName = "collection name";
    
    // This will save all of the documents in the file you specified
    WriteCollectionToFile(database, collectionName, fileName).Wait();
    
    // This will drop all of the documents in the collection
    Task.Factory.StartNew(() => database.GetCollection(collectionName).DeleteManyAsync(new BsonDocument())).Wait();
    
    // This will restore all the documents from the file you specified
    LoadCollectionFromFile(database, collectionName, fileName).Wait();
    

    请注意,此代码是使用 MongoDB C# 驱动程序的 2.0 版编写的,您可以通过 Nuget 获得该驱动程序。另外LoadCollectionFromFile方法中的文件读取代码是从this answer获取的。

    【讨论】:

    • 谢谢,我会试试的。您的答案中有很多东西我仍然需要学习 - 任务、异步等,但我最终会到达那里。
    • 同时 - 另一个问题:'File.WriteAllText' 和 'File.AppendAllLines' 是否适用于 非常大的 文件?像几个GB?它必须将文件的全部内容保存在内存中,还是按顺序写入?
    • @Mike File.WriteAllText 调用只是为了确保在您启动时文件为空。 File.AppendAllLines 即使处理非常大的文件也应该可以正常工作,因为您一次只附加一个文档。但是,其他函数中的File.ReadAllLines 可能会给您带来一些麻烦。我将对其进行更新以提高性能...
    • 此外,由于每个文档都被写入文件中的新行,然后该文件一次读取一行,因此换行符被有效地用作分隔符。如果您的 BSON 也包含换行符,这可能会导致问题 - YMMV,您可能需要尝试使用不同的分隔符。
    【解决方案2】:

    您可以使用 C# BinaryFormatter 将对象图序列化到磁盘。您也可以反序列化回对象图。

    序列化: https://msdn.microsoft.com/en-us/library/c5sbs8z9%28v=VS.110%29.aspx

    反序列化: https://msdn.microsoft.com/en-us/library/b85344hz%28v=vs.110%29.aspx

    但这不是 mongodb 或 C# 驱动程序功能。

    序列化后,您可以使用驱动程序删除集合。反序列化后,您可以使用驱动程序将对象插入新集合中。

    根据您的规则,您可能希望在执行导出过程时对该集合进行一些锁定,然后再删除它。

    【讨论】:

    • 谢谢艾哈迈德。我试图将数据存储在数据库中的主要原因是数据量太大而且我的内存不足异常。给你一些想法:我正在处理大约 1000 万个 class 实例,每个实例都包含十几个属性(双精度数、字符串等)。测试必须计算该数据的各种统计数据。我的想法是,如果我将数据存储在 MongoDB 中,而不是保存在 RAM 中 - 我仍然可以以类似 LINQ 的方式(Mongo 允许)处理数据 - 这将花费更多时间,
    • 因为 Monogo 必须从硬盘上加载所需的部分,但至少我不会离开内存。二进制序列化和去反序列化是否允许我处理数据,**当在给定时刻只有部分数据在内存中时**?
    • 我不太清楚你为什么要特别处理这么多数据。但是,您可以加载集合文档的补丁并将它们序列化为磁盘上的多个文件。根据您的可用内存,您可以决定一次加载多少文档。反序列化时,您将遍历您的“.dat”文件,例如逐个处理它们以将数据移回 Mongo。
    猜你喜欢
    • 2015-06-13
    • 2019-09-04
    • 2018-12-25
    • 2013-08-06
    • 1970-01-01
    • 2020-04-29
    • 1970-01-01
    • 2021-11-08
    • 2019-05-06
    相关资源
    最近更新 更多