首页 > 解决方案 > C# - Cosmos DB 批量更新插入

问题描述

我有一个由计时器触发的 Azure 函数,我想在其中更新 CosmosDB 中的文档。现在我使用UpdateOneAsync带有选项的函数IsUpsert = true进行更新(或者如果文档不存在则插入)。

但是,我在 foreach 循环中执行更新操作,因此对每个项目执行更新操作。如何进行批量更新(upsert),在 foreach 循环完成后只执行一项操作?

这是我现在的代码:

foreach (var group in GetGroups(date, time, hour))
{
    dic = new MyDictionary<string>();

    //... some operations

    List<BsonElement> documents = new List<BsonElement>();
    documents.Add(new BsonElement("$inc", new BsonDocument(dic)));
    documents.Add(new BsonElement("$set", new BsonDocument(new Dictionary<string, string>() { { "c", key }, { "d", date } })));

    var doc = clicksDoc.UpdateOneAsync(t => t["_id"] == "c-" + key + "-" + date, new BsonDocument(documents), new UpdateOptions() { IsUpsert = true }).Result;
}

相反,我想在循环之后只执行一次更新。我怎样才能做到这一点?

标签: c#azure-cosmosdbupsertbulk

解决方案


2020年答案

.NET SDK 中添加了批量支持:
在 .NET SDK 中引入批量支持

要使用它,首先在创建客户端时启用批量执行:

CosmosClient client = new CosmosClientBuilder(options.Value.ConnectionString)
    .WithConnectionModeDirect()
    .WithBulkExecution(true)
    .Build();

然后像往常一样获取您的容器:

Container container = client.GetContainer("databaseName", "containerName");

然后进行批量操作,例如 upsert:

public async Task BulkUpsert(List<SomeItem> items)
{
    var concurrentTasks = new List<Task>();

    foreach (SomeItem item in items)
    {
        concurrentTasks.Add(container.UpsertItemAsync(item, new PartitionKey(item.PartitionKeyField)));
    }

    await Task.WhenAll(concurrentTasks);
}

推荐阅读