如何使用C#将整个MongoDB集合保存到json/bson文件?

如何使用C#将整个MongoDB集合保存到json/bson文件?,c#,json,mongodb,bson,C#,Json,Mongodb,Bson,我有一个过程,首先生成大量数据并保存到mongoDB集合中,然后分析数据,最后-我想将整个集合保存到磁盘上的文件中,并擦除集合。 我知道我可以用MongoDump.exe轻松地完成这项工作,但我想知道是否有任何方法可以直接从c#完成这项工作我的意思是不使用控制台进程,而是使用MongoC#driver中的一些功能 如果可以的话,我怎么做c#中的反向操作呢即:将.bson文件加载到集合中?您可以使用C#BinaryFormatter将对象图序列化到磁盘。还可以反序列化回对象图 序列化: 反序列化

我有一个过程,首先生成大量数据并保存到mongoDB集合中,然后分析数据,最后-我想将整个集合保存到磁盘上的文件中,并擦除集合。 我知道我可以用MongoDump.exe轻松地完成这项工作,但我想知道是否有任何方法可以直接从c#完成这项工作我的意思是不使用控制台进程,而是使用MongoC#driver中的一些功能

如果可以的话,我怎么做c#中的反向操作呢即:将.bson文件加载到集合中?

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

序列化:

反序列化:

然而,这不是mongodb或C#驱动程序的特性

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


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

以下是两种方法,可用于完成此操作:

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));
        }
    }
}

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

感谢Ahmed。我尝试将数据存储在数据库中的主要原因是数据量太大,并且内存不足。让您了解一下:我正在处理约1000万个类实例,每个实例都包含十几个属性(双精度、字符串等)。测试必须计算该数据的各种统计数据。我的想法是,如果我将数据存储在MongoDB中,而不是保存在RAM中-我仍然可以以类似LINQ的方式(Mongo允许)处理数据-这将需要更多的时间,因为Monogo必须从硬盘上加载所需的部分,但至少我不会离开memroy。二进制序列化和去序列化是否允许我处理数据,**当给定时刻内存中只有一部分数据**?我不太清楚为什么要特别处理这么多数据。但是,您可以加载集合文档的修补程序,并将其序列化到磁盘上的多个文件中。根据可用内存,您可以决定一次加载多少文档。例如,当反序列化时,您可以循环遍历“.dat”文件,逐个处理它们以将数据移回Mongo。谢谢,我将尝试这样做。在你的回答中,我还有很多东西需要学习——任务、异步等,但我最终会做到。与此同时,还有一个问题:“File.writealText”和“File.AppendAllLines”是否能处理真正大的文件?像几GB?它必须将文件的全部内容保存在内存中,还是按顺序写入?@Mike the
file.writealText
调用就是为了确保启动时文件是空的<代码>文件.AppendAllLines即使对于非常大的文件也可以正常工作,因为一次只追加一个文档。但是,另一个函数中的
File.ReadAllLines
可能会给您带来一些麻烦。我将对其进行更新以提高性能……此外,由于每个文档都被写入文件中的新行,然后该文件一次读取一行,因此新行字符实际上被用作分隔符。如果您的BSON也包含换行符(YMMV),这可能会导致问题,您可能需要尝试使用不同的分隔符。
// 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();