[英]Is a MongoDB bulk upsert possible? C# Driver
我想在蒙哥做一個大批量增補。 基本上,我從供應商那里獲得了對象列表,但是我不知道我之前(需要更新)哪些對象以及哪些是新對象。 我可以一個接一個地進行upsert,但UpdateMany不適用於upsert選項。
因此,我不得不選擇文檔,使用C#更新並進行批量插入。
public async Task BulkUpsertData(List<MyObject> newUpsertDatas)
{
var usernames = newUpsertDatas.Select(p => p.Username);
var filter = Builders<MyObject>.Filter.In(p => p.Username, usernames);
//Find all records that are in the list of newUpsertDatas (these need to be updated)
var collection = Db.GetCollection<MyObject>("MyCollection");
var existingDatas = await collection.Find(filter).ToListAsync();
//loop through all of the new data,
foreach (var newUpsertData in newUpsertDatas)
{
//and find the matching existing data
var existingData = existingDatas.FirstOrDefault(p => p.Id == newUpsertData.Id);
//If there is existing data, preserve the date created (there are other fields I preserve)
if (existingData == null)
{
newUpsertData.DateCreated = DateTime.Now;
}
else
{
newUpsertData.Id = existingData.Id;
newUpsertData.DateCreated = existingData.DateCreated;
}
}
await collection.DeleteManyAsync(filter);
await collection.InsertManyAsync(newUpsertDatas);
}
有沒有更有效的方法可以做到這一點?
編輯:
我做了一些速度測試。
在准備過程中,我插入了一個相當簡單的對象的100,000條記錄。 然后,我向該集合中添加了200,000條記錄。
方法1如問題中所述。 SelectMany,更新代碼,DeleteMany,InsertMany。 這花費了大約5秒鍾。
方法2是使用Upsert = true列出UpdateOneModel的列表,然后執行一個BulkWriteAsync。 這太慢了。 我可以看到mongo集合中的計數增加了,所以我知道它正在運行。 但是大約5分鍾后,它只攀升到107,000,所以我取消了它。
我仍然對其他人是否有潛在的解決方案感興趣
假設您已經說過可以進行一對一的upsert,則可以使用BulkWriteAsync
實現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);
所有這一切的關鍵是IsUpsert
物業UpdateOneModel
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.