是否可以使用MongoDB批量转发? C#驱动程序

时间:2017-11-03 21:20:40

标签: c# mongodb

我想在Mongo中做一个大量的upsert。基本上我从供应商那里得到一个对象列表,但我不知道我之前得到了哪些(并且需要更新)与哪些是新的。我可以逐个进行upsert,但UpdateMany不能使用upsert选项。

因此,我选择了文档,使用C#进行更新,并进行批量插入。

#include "stdafx.h"
#include <iostream>
#include <vector>
#include <string>
#include <experimental/filesystem> 
#include <fstream>

using namespace std;

std::vector<std::string> get_filenames(std::experimental::filesystem::path path)
{
    namespace stdfs = std::experimental::filesystem;
    std::vector<std::string> filenames;
    const stdfs::directory_iterator end{};
    for (stdfs::directory_iterator iter{ path }; iter != end; ++iter)
    {
        if (stdfs::is_regular_file(*iter)) 
            filenames.push_back(iter->path().string());
    }
    return filenames;
}



void Dirloop(){
    for (const auto& name : get_filenames(".")) std::cout << name << '\n';
}


void Outfile() {

    std::ofstream outputFile("data.txt", std::ios::out);
    outputFile << name << std::endl;
    outputFile.close();
    cout << "Generated data.txt!\n";
}

int main()
{
    Dirloop();
    Outfile();
    std::getchar();
    return 0;
}

有更有效的方法吗?

编辑:

我做了一些速度测试。

在准备中,我插入了一个非常简单的对象的100,000条记录。然后我将200,000条记录发送到该集合中。

方法1如问题中所述。 SelectMany,代码更新,DeleteMany,InsertMany。这花了大约5秒钟。

方法2使用Upsert = true制作UpdateOneModel列表,然后执行一次BulkWriteAsync。这太慢了。我可以看到mongo集合中的计数增加,所以我知道它正在工作。但是大约5分钟之后,它只上升到了107,000,所以我取消了它。

如果其他人有可能的解决方案,我仍然感兴趣

1 个答案:

答案 0 :(得分:2)

鉴于你已经说过你可以做一个一个一个的upsert,你可以用BulkWriteAsync实现你想要的。这允许您创建一个或多个抽象WriteModel的实例,在您的情况下,它将是UpdateOneModel的实例。

为了实现这一目标,您可以执行以下操作:

var listOfUpdateModels = new List<UpdateOneModel<T>>();

// ...

var updateOneModel = new UpdateOneModel<T>(
    Builders<T>.Filter. /* etc. */,
    Builders<T>.Update. /* etc. */)
{
    IsUpsert = true;
};

listOfUpdateModels.Add(updateOneModel);

// ...

await mongoCollection.BulkWriteAsync(listOfUpdateModels);

所有这一切的关键是UpdateOneModel上的IsUpsert属性。