MongoDB 是否可以批量更新插入?C# 驱动程序

bgr*_*ham 1 c# mongodb

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

因此,我采取了选择文档、用 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);
    }
Run Code Online (Sandbox Code Playgroud)

有没有更有效的方法来做到这一点?

编辑:

我做了一些速度测试。

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

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

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

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

Kir*_*kin 7

鉴于您已经说过您可以进行一对一的更新插入,您可以通过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);
Run Code Online (Sandbox Code Playgroud)

这一切的关键IsUpsertUpdateOneModel.