我想在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,所以我取消了它。
如果其他人有可能的解决方案,我仍然感兴趣
答案 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
属性。